这对我来说是一个很奇怪的错误。检查以下代码:
void test(void){
vector<string> v;
v.push_back("hello");
auto fn=[=](){
v.push_back("world");
};
}
第一个 push_back 方法传递了编译,但第二个失败,产生错误:
错误:没有匹配的成员函数来调用'push_back'
编译器注释是:
**注意:(687,36)候选函数不可行:'this'参数的类型为'const vector'(又名'const vector,allocator&gt;&gt;')
但该方法未标记为const**
好吧,我没有使用任何const参数,我无法弄清楚编译器试图告诉我什么。有人能帮助我吗?
答案 0 :(得分:10)
默认情况下,Lambda调用运算符成员函数为const
。如果您想要一个可变调用运算符,请说mutable
:
auto fn = [=]() mutable {
// ^^^^^^^
v.push_back("world");
};
让const
成为默认值会强制您明确表示您想要捕获向量的副本并改变该副本,而不是原始向量{{1 }}
相比之下,通过引用捕获的变量可以通过const限定的成员函数进行突变:
v
(这主要是因为在auto fn = [&]() {
// ^^^
v.push_back("world"); // modifies original "V"!
};
时const T
与T
相同;在C ++中没有&#34;常量引用&#34;。
答案 1 :(得分:4)
按值const
捕获使用关键字mutable
(不会更改原始向量):
auto fn = [=]() mutable {
v.push_back("world");
};
或通过引用(更改原始向量):
auto fn = [&]() {
v.push_back("world");
};
答案 2 :(得分:0)
由于C++14
标记,为了完整起见,我还引用初始化列表作为替代解决方案:
[&vec = v](){ vec.push_back("world") };
如果您想通过副本而不是通过引用进行捕获:
[vec = v]() mutable { vec.push_back("world") };
初始化程序列表(我说)捕获方法自C++14
起可用,如前所述。