为什么使用Lambdas / Closures调用CopyConstructor?

时间:2016-10-10 18:43:28

标签: c++ c++11 lambda closures copy-constructor

#include <iostream>
#include <typeinfo>

struct C {
    explicit C() {std::cout << "constructor" << std::endl; }
    C (const C&) { std::cout << "copyconstructor" << std::endl;}
    ~C() { std::cout << "destructor" << std::endl; }
};

int main(){
    C c1;
    auto f = [c1](){c1;};
    std::cout << "leaving function scope" << std::endl;
    return 0;
}

编译

g++ -o a -std=c++11 test.cpp -fno-elide-constructors

生成输出:

constructor copyconstructor copyconstructor destructor leaving function scope destructor destructor

使用

进行编译
g++ -o a -std=c++11 test.cpp

生成输出:

constructor copyconstructor leaving function scope destructor destructor

由于我在第二次编译中跳过了-fno-elide-constructors编译器选项,为什么生成的代码仍然会调用一次CopyConstructor?我建议g++编译器会自动使用复制省略来初始化auto f,就像初始化闭包一样,这会导致:

constructor construtor leaving function scope destructor destructor

1 个答案:

答案 0 :(得分:1)

  

我建议g ++编译器会自动使用copy elision来初始化auto f,就像初始化闭包一样

但它没有使用copy elision来初始化闭包。您看到的唯一copyconstructor闭包变量的初始化。这无法消除。即使在C ++ 17中;你将永远拥有2个C对象,其中一个是从另一个复制的。

如果您希望lambda仅引用外部范围,那么您应该通过引用捕获变量:[&c1]。按值捕获意味着复制它。