C++14 新特性
目录
读写锁std::shared_timed_mutex和std::shared_lock
lambda 初始化捕获
Abstract
可以对捕获列表的捕获变量“赋值”,C++14中的这个新特性允许了在捕获列表中定义前面没有出现过的变量,但必须赋予一个值,并且不使用类型说明符和auto,类型由编译器自动推断。
Demo
#include <cmath> #include <iostream> using namespace std; int main() { int a = 2; [a = sin(a)]() { cout << a << endl; // 0.909297 cout << cos(a) << endl; // 0.6143 }(); cout << a << endl; // 2 cout << cos(a) << endl; // -0.416147 return 0; }
废弃标志[[deprecated]]
Abstract
C++14中增加了[[deprecated]]标记,可以修饰类、函数、变量等,当程序中使用了被其修饰的模块时,编译器会产生告警,提示用户该标记标记的内容将来可能会被废弃,尽量不要使用。
Demo
struct [[deprecated]] Tmp {};
读写锁std::shared_timed_mutex和std::shared_lock
Abstract
C++14中通过std::shared_timed_mutex和std::shared_lock实现读写锁,保证多个线程可以同时读,但是写线程必须独立运行,写操作不能和读操作同时进行。
Demo
struct ThreadSafe { mutable std::shared_timed_mutex _mutex; int _value; ThreadSafe() { _value = 0; } int get() const { std::shared_lock<std::shared_timed_mutex> loc(_mutex); return _value; } void increase() { std::unique_lock<std::shared_timed_mutex> lock(_mutex); _value += 1; } };
模板可变整数序列
Abstract
类模板 std::integer_sequence 表示一个编译时的整数序列。在用作函数模板的实参时,能推导参数包 Ints 并将它用于包展开。
Demo
#include <array> #include <iostream> #include <tuple> #include <utility> template <typename T, T... ints> void print_sequence(std::integer_sequence<T, ints...> int_seq) { std::cout << "The sequence of size " << int_seq.size() << ": "; ((std::cout << ints << ' '), ...); std::cout << '\n'; } // 转换数组为 tuple template <typename Array, std::size_t... I> auto a2t_impl(const Array &a, std::index_sequence<I...>) { return std::make_tuple(a[I]...); } template <typename T, std::size_t N, typename Indices = std::make_index_sequence<N>> auto a2t(const std::array<T, N> &a) { return a2t_impl(a, Indices{}); } // 漂亮地打印 tuple template <class Ch, class Tr, class Tuple, std::size_t... Is> void print_tuple_impl(std::basic_ostream<Ch, Tr> &os, const Tuple &t, std::index_sequence<Is...>) { ((os << (Is == 0 ? "" : ", ") << std::get<Is>(t)), ...); } template <class Ch, class Tr, class... Args> auto &operator<<(std::basic_ostream<Ch, Tr> &os, const std::tuple<Args...> &t) { os << "("; print_tuple_impl(os, t, std::index_sequence_for<Args...>{}); return os << ")"; } int main() { print_sequence(std::integer_sequence<unsigned, 9, 2, 5, 1, 9, 1, 6>{}); print_sequence(std::make_integer_sequence<int, 20>{}); print_sequence(std::make_index_sequence<10>{}); print_sequence(std::index_sequence_for<float, std::iostream, char>{}); std::array<int, 4> array = {1, 2, 3, 4}; // 转换 array 为 tuple auto tuple = a2t(array); static_assert(std::is_same<decltype(tuple), std::tuple<int, int, int, int>>::value, ""); // 打印到 cout std::cout << tuple << '\n'; }
改变exchange
Abstract
相对于swap不对后者赋值
Demo
#include <iostream> #include <utility> #include <vector> using namespace std; int main() { vector<int> vec1{1, 2, 3, 4}; vector<int> vec2{5, 6, 7, 8}; cout << "exchange before: " << endl; cout << "vec1: " << endl; copy(vec1.begin(), vec1.end(), ostream_iterator<int>{cout, " "}); cout << endl << "vec2: " << endl; copy(vec2.begin(), vec2.end(), ostream_iterator<int>{cout, " "}); exchange(vec1, vec2); cout << endl << "exchange after: " << endl; cout << "vec1: " << endl; copy(vec1.begin(), vec1.end(), ostream_iterator<int>{cout, " "}); cout << endl << "vec2: " << endl; copy(vec2.begin(), vec2.end(), ostream_iterator<int>{cout, " "}); return 0; }
字符串带引号
Abstract
#include <iomanip> #include <iostream> #include <string> int main() { std::string str{"hello world"}; std::cout << str << std::endl; // hello world std::cout << std::quoted(str) << std::endl; // "hello world" return 0; }