C++1x的应用总结之一移动捕获

C++1x的应用总结之一移动捕获

在应用的工程中看到了如下的代码,以前还真没这么用过:

auto&& task = [e = std::move(ptr)]() mutable {

                           processTransaction(std::move(e));

查了下资料,在C++11中,对移动对象(如std::unique_ptr或std::future)放入到闭包里(就简单理解成lambda表达式),而实际情况经常有一个对象拷贝的代价比较高,但是移动的代码很小。这事儿在以前就比较麻烦了,不过C++14里做了一个十分巧妙的方式来解决了这种情况,即上面的代码的那种情况。

分析一下:

这个e代表是闭包里的变量,编译器看到这种声明会自动在闭包内声明这个auto  e,类型是自动推导出来的。所以大家不要以为C++也可以不做强类型声明了。明白了这一点,估计其它就不用说了。

其实下面这种方式更容易让初接触的头大:

int a = 0; 

int get(inta){return a+1;}

int main(void)

{

………….

    [a = get(a)]() 

   { 

       cout << a << endl; 

}();

……………….

}

但是一按上面的分析发现就非常简单了。两个小a不是一个变量,=号左面的是闭包内部自动声明的,由编译器来推导类型。后面的小a是捕获的外面的变量。

不过真正有意义的应该还是最上面介绍的在移动时的意义。

如果在C++11中不能使用这种特性,事情也就比较不好办了,但是可以类似于函数指针和std::function来写,或者说用bind来实现。

多说一句,看Lambda表达式(C++11 起)的说明:

构造一个闭包:能够捕获作用域中变量的无名函数。

语法

[ capture-list] ( params ) mutable(可选) constexpr(可选)(C++17) exception attribute -> ret { body }  (1)   

[ capture-list ] ( params ) ->ret { body }        (2)   

[ capture-list] ( params ) { body }     (3)   

[ capture-list] { body }      (4)   

看上面给的例程:

struct X {

    int x, y;

    int operator()(int);

    void f()

    {

        // 下列lambda的语境是成员函数X::f

        [=]()->int

        {

            return operator()(this->x + y);// X::operator()(this->x + (*this).y)

                                            //this拥有类型X*

        };

    }

};

和这个:

int&(*fpi)(int*) = [](auto* a)->auto& { return *a; }; // ok

这两个例程出自:

http://zh.cppreference.com/w/cpp/language/lambda

新技术和新思想层出不穷啊,有点儿力拙的表现。

猜你喜欢

转载自blog.csdn.net/fpcc/article/details/74439227