lambda表达式中没有匹配的成员函数错误?

时间:2016-04-19 14:49:43

标签: c++ c++11 lambda

这对我来说是一个很奇怪的错误。检查以下代码:

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参数,我无法弄清楚编译器试图告诉我什么。有人能帮助我吗?

3 个答案:

答案 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 TT相同;在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起可用,如前所述。