代码中C++11一些新的特性
2017-04-13 18:27
211 查看
通过result_of multimap<typename std::result_of<Fn(Person)>::type, Person> std::result_of<Fn(Arg)>::type可以获取function的返回值,没有魔法数,也没有declval繁琐的写法,很优雅。其实,查看源码就知道result_of内部就是通过declval实现的,作法和方式二一样,只是简化了写法。
std::function<int(int)> fr2,那么fr2就可以代表返回值和参数表相同的一类函数。 std::bind用来将可调用对象与其参数一起进行绑定。绑定后可以使用std::function进行保存,并延迟到我们需要的时候调用: (1) 将可调用对象与其参数绑定成一个仿函数; (2) 可绑定部分参数。 在绑定部分参数的时候,通过使用std::placeholders来决定空位参数将会是调用发生时的第几个参数。
A a; // 绑定成员函数,保存为仿函数 std::function<void(int, int)> fr = std::bind(&A::output, &a, std::placeholders::_1, std::placeholders::_2); // 调用成员函数 fr(1, 2); // 绑定成员变量 std::function<int&(void)> fr2 = std::bind(&A::i_, &a); fr2() = 100;// 对成员变量进行赋值 std::cout << a.i_ << std::endl;
可以看到once_flag是不允许修改的,拷贝构造函数和operator=函数都声明为delete,这样防止程序员乱用。 另外,call_once也是很简单的,只要传进一个once_flag,回调函数,和参数列表就可以了。 #include <iostream> #include <thread> #include <mutex> std::once_flag flag; void do_once() { std::call_once(flag, [](){ std::cout << "Called once" << std::endl; }); } int main() { std::thread t1(do_once); std::thread t2(do_once); std::thread t3(do_once); std::thread t4(do_once); t1.join(); t2.join(); t3.join(); t4.join(); } 可以看到,只会输出一行 Called once 值得注意的是,如果在函数执行中抛出了异常,那么会有另一个在once_flag上等待的线程会执行。 实际上once_flag相当于一个锁,使用它的线程都会在上面等待,只有一个线程允许执行。如果该线程抛出异常,那么从等待中的线程中选择一个,重复上面的流程。
emplace操作是C++11新特性,新引入的的三个成员emlace_front、empace 和 emplace_back, 这些操作构造而不是拷贝元素到容器中,这些操作分别对应push_front、insert 和push_back,允许我们将元素放在容器头部、一个指定的位置和容器尾部。 emplace函数在容器中直接构造元素,传递给emplace函数的参数必须与元素类型的构造函数相匹配。
std::forward 函数功能 std::forward<T>(u) 有两个参数:T 与 u。当T为左值引用类型时,u将被转换为T类型的左值,否则u将被转换为T类型右值。如此定义std::forward是为了在使用右值引用参数的函数模板中解决参数的完美转发问题。
std::future:
std::future 介绍 前面已经多次提到过 std::future,那么 std::future 究竟是什么呢?简单地说,std::future 可以用来获取异步任务的结果,因此可以把它当成一种简单的线程间同步的手段。 std::future 通常由某个 Provider 创建,你可以把 Provider 想象成一个异步任务的提供者,Provider 在某个线程中设置共享状态的值,与该共享状态相关联的 std::future 对象调用 get(通常在另外一个线程中) 获取该值, 如果共享状态的标志不为 ready,则调用 std::future::get 会阻塞当前的调用者,直到 Provider 设置了共享状态的值(此时共享状态的标志变为 ready),std::future::get 返回异步任务的值或异常(如果发生了异常)。 一个有效(valid)的 std::future 对象通常由以下三种 Provider 创建,并和某个共享状态相关联。Provider 可以是函数或者类,其实我们前面都已经提到了,他们分别是: std::async 函数,本文后面会介绍 std::async() 函数。 std::promise::get_future,get_future 为 promise 类的成员函数,详见 C++11 并发指南四(<future> 详解一 std::promise 介绍)。 std::packaged_task::get_future,此时 get_future为 packaged_task 的成员函数,详见C++11 并发指南四(<future> 详解二 std::packaged_task 介绍)。 一个 std::future 对象只有在有效(valid)的情况下才有用(useful),由 std::future 默认构造函数创建的 future 对象不是有效的(除非当前非有效的 future 对象被 move 赋值另一个有效的 future 对象)。 在一个有效的 future 对象上调用 get 会阻塞当前的调用者,直到 Provider 设置了共享状态的值或异常(此时共享状态的标志变为 ready),std::future::get 将返回异步任务的值或异常(如果发生了异常)。
相关文章推荐
- C++11中的一些新特性
- 编译使用了C++11特性的代码
- 跟Google学写代码--Chromium工程中用到的C++11特性(Library Features)
- 跟Google学写代码--Chromium工程中用到的C++11特性(Library Features)
- Java一些特性的示例代码
- 一些常用的C++11新增特性
- c++11的一些特性auto和范围for循环
- C++11中一些新语言特性与相似特性的比较
- 跟Google学写代码--Chromium工程中禁止使用的C++11特性
- Qt5 中对 C++11 一些新特性的封装
- 一些C++11语言新特性 - Uniform Initialization
- C++11新特性(五)看看外国佬写的代码move的使用
- C++11新特性:Lambda函数(匿名函数) 一段代码即可理解
- 使用eclipse编译含有C++11特性的代码
- C++11的一些新特性
- 使用eclipse编译含有C++11特性的代码
- 一些C++11语言新特性 - Range-Based for Loops
- 跟Google学写代码--Chromium工程中用到的C++11特性
- 使用eclipse编译含有C++11特性的代码