了解Lambda闭包类型如何删除默认构造函数

时间:2015-10-02 16:30:31

标签: c++ constructor lambda default

从5.1.2开始

  

[19]与lambda表达式关联的闭包类型具有已删除(8.4.3)的默认构造函数并且已删除   复制赋值运算符。它有一个隐式声明的复制构造函数(12.8),可能有一个隐式声明   移动构造函数(12.8)。 [注意:复制/移动构造函数以相同的方式隐式定义   因为任何其他隐式声明的复制/移动构造函数都将被隐式定义。 - 后注]

我正在阅读C ++ Primer 14.8.1,它解释了编译器将lambda表达式转换为未命名类的未命名对象。如果删除默认构造函数,我怎么能定义不包含lambda捕获的lambda函数的对象?

 auto g = [](){};

这在概念上与......相同吗

 class lambdaClass{
 public:
      lambdaClass() = delete;
      lambdaClass& operator=(const lambdaClass&) = delete;
      void operator()(){ }

      //copy/move constructor and destructor implicitly defined
};

auto g = lambdaClass(); //would be an error since default is deleted.

如果有捕获,那么将定义构造函数其他而不是默认构造函数,并且可以初始化此类对象(只要传递参数)。但是如果没有捕获并且删除了默认构造函数,那么在概念上似乎不能创建lambda类对象。

编辑:嗯,也许lambda类根据其lambda捕获创建构造函数的概念是没有根据的,尽管这是它在C ++ Primer中的描述(我在标准中找不到它的引用),因为以下代码不起作用,即使我希望它在概念上:

int sz = 2;
auto a = [sz](){ return sz;};
decltype(a) b(10); //compiler error
decltype(a) b = a; //all good though

2 个答案:

答案 0 :(得分:6)

关闭 lambda 之间的关系类似于对象

C ++ 11标准表示 closure!类型没有默认构造函数,这是正确的,因为它没有说它没有构造函数。< / p>

lambda用于创建闭包。但是你引用的parapgraph将改为 C ++ 14

ClosureType() = delete;                     // (until C++14)
ClosureType(const ClosureType& ) = default; // (since C++14)
ClosureType(ClosureType&& ) = default;      // (since C++14)
  

关闭类型不是DefaultConstructible。闭包类型具有a deleted (until C++14) no (since C++14)默认构造函数。复制构造函数和移动构造函数是implicitly-declared (until C++14)声明的as defaulted (since C++14),可以根据复制构造函数和移动构造函数的通常规则进行隐式定义。

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

答案 1 :(得分:0)

因为赋值的右边是一个临时对象(右值),所以'g'是通过移动赋值来赋值的