• 代码中C++11一些新的特性


    通过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 将返回异步任务的值或异常(如果发生了异常)。
  • 相关阅读:
    灭霸冲刺(7)
    灭霸冲刺(6)
    灭霸冲刺(5)
    灭霸冲刺(4)
    pip安装软件或模块时提示cannot import name 'main'
    mysql的安装与使用
    channels 2.x的使用
    charlesmitmproxyappium的安装与使用
    centos中redis安装
    django+nginx+gunicorn+pipenv微信小程序实践笔记
  • 原文地址:https://www.cnblogs.com/ph829/p/6705394.html
Copyright © 2020-2023  润新知