N4140(大约是C++14)说:
5.1.2 Lambda表达式[expr.prim.lambda]
20 与
lambda表达式相关联的闭包类型具有已删除的(8.4.3)默认构造函数和已删除的复制赋值运算符。它具有一个隐式声明的复制构造函数(12.8),并且可能具有一个隐式声明的移动构造函数(12.8)。[
注意:复制/移动构造函数的隐式定义方式与任何其他隐式声明的复制/移动构造函数的隐式定义方式相同。
-- end note]
请注意,这并未提及是否隐式声明了已删除的复制赋值运算符。编译器将lambda转换为类定义和实例化,但该类可以以巧妙的方式定义,其中复制赋值运算符被隐式声明,但该类的某些其他属性导致该隐式复制赋值运算符被删除。
然后:
12.8 复制和移动类对象[class.copy]
20 如果类 X
的定义没有显式声明移动赋值运算符,那么只有在以下条件下才会隐式声明为默认的:
(20.1) -- X
没有用户声明的复制构造函数,
(20.2) -- X
没有用户声明的移动构造函数,
(20.3) -- X
没有用户声明的复制赋值运算符,并且
(20.4) -- X
没有用户声明的析构函数。
如果 lambda 函数的复制赋值运算符被隐式声明,则不会抑制移动赋值运算符的生成。如果它被显式声明,则移动赋值运算符将被禁止。
这两种行为都可以根据标准的字面措辞得到证明。
这部分问题已经在 CWG issue 1891 中得到部分解决,其中修改了文本如下:
与
lambda表达式相关的闭包类型没有默认构造函数和删除的复制赋值运算符。它有一个默认的复制构造函数和一个默认的移动构造函数(12.8 [class.copy])。[
注意:这些特殊成员函数通常会被隐式定义,并因此可能被定义为已删除。
-- 结束说明]
然而,尽管移动赋值运算符在该问题中被提出为一个问题,但它并不改变答案,它仍然保持开放的可能性。