Omn*_*ity 61 c++ lambda language-lawyer c++11
例:
#include <functional>
int main() {
auto test = []{};
test = []{};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这会在gcc 4.7.2中发出以下错误消息:
test.cpp: In function ‘int main()’:
test.cpp:5:13: error: no match for ‘operator=’ in ‘test = <lambda closure object>main()::<lambda()>{}’
test.cpp:5:13: note: candidate is:
test.cpp:4:16: note: main()::<lambda()>& main()::<lambda()>::operator=(const main()::<lambda()>&) <deleted>
test.cpp:4:16: note: no known conversion for argument 1 from ‘main()::<lambda()>’ to ‘const main()::<lambda()>&’
Run Code Online (Sandbox Code Playgroud)
从标准5.1.2.3(强调我的):
实现可以定义闭包类型与下面描述的不同,前提是这不会改变程序的可观察行为,只需更改:
- 封闭类型的大小和/或对齐方式,
- 封闭类型是否可以轻易复制(第9条)
- 闭包类型是否为标准布局类(第9条),或
- 闭包类型是否为POD类(第9条).
据我所知,这就是我遇到的情况.它试图使用已删除的赋值运算符并失败.我很想知道是否有一个简单的解决方法,更广泛地说,一般来说,为lambdas省略复制可构造性的动机理由是什么.
Dan*_*rey 69
你似乎认为那两个lambda具有相同的类型,但事实并非如此.每个人都创建自己的类型:
#include <functional>
#include <type_traits>
#include <iostream>
int main() {
auto test = []{};
auto test2 = []{};
std::cout << std::is_same< decltype( test ), decltype( test2 ) >::value << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将打印0
.当然,在这方面,您从编译器获得的错误消息可能会更加清晰......
And*_*zos 47
lambda表达式的类型(也是闭包对象的类型)是一个唯一的,未命名的非联合类类型
所以就像你正在做以下事情:
struct {} a;
struct {} b;
a = b; // error, type mismatch
Run Code Online (Sandbox Code Playgroud)
使用std::function
,如果你想用相同的签名相同的变量分配不同的lambda表达式.
std::function<void()> f = []{};
f = []{}; //ok
Run Code Online (Sandbox Code Playgroud)
Lambda无法重新定义,因为每个lambda都是不同的,匿名的,不兼容的类型.只有将它们传递给std::function
能够推导出该类型的模板化函数(如ctor)时,才能复制它们.
之所以无法执行此操作,是因为lambda表达式的副本分配运算符被声明为已删除,请参见标准的5.1.2 / 20。有关更清晰的说明(有关clear的异常定义),请参见以下代码示例
template<class T> void f(T x1)
{
T x2 = x1; // copy constructor exists, this operation will succeed.
x2 = x1; // assignment operator, deleted and will cause an error
}
int main()
{
f([]{});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
其他答案指出,每个lambda都有一个唯一的类型,但这不是导致该错误的原因。此示例显示,即使两个lambda具有相同的类型,也仍然无法复制它。但是,您可以将其复制到新变量。这就是您的错误消息抱怨缺少的原因,operator=
而不是抱怨它们的类型不同的原因。尽管每个具有自己的类型的lambda都不能帮上大忙。