Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No matching member function error inside lambda expression?

Tags:

c++

c++11

lambda

This is quite a strange error to me. Check the code below:

void test(void){
    vector<string> v;
    v.push_back("hello");
    auto fn=[=](){
        v.push_back("world");
    };
}

The first push_back method passed the compilation but the second failed, yielding the error:

Error:no matching member function for call to 'push_back'

The compiler note is:

**Note:(687, 36) candidate function not viable: 'this' argument has type 'const vector' (aka 'const vector, allocator > >')

But the method is not marked const**.
Well I am not using any const argument and I cannot figure what the compiler is trying to tell me. Could anybody help me?

like image 893
Heranort Avatar asked Apr 19 '16 14:04

Heranort


People also ask

How to fix the error no matching function for call to in c++?

To fix this error during the method call, we must provide adequate corresponding parameters to the function. The other way of resolving this error is to make different overloaded functions have different parameters. Here we just modify the argument of the function main().

What is the correct syntax for lambda expression in C++11?

Lambdas can both capture variables and accept input parameters. A parameter list (lambda declarator in the Standard syntax) is optional and in most aspects resembles the parameter list for a function. auto y = [] (int first, int second) { return first + second; };

How to define a lambda in c++?

C++ 11 introduced lambda expressions to allow inline functions which can be used for short snippets of code that are not going to be reused and therefore do not require a name. In their simplest form a lambda expression can be defined as follows: [ capture clause ] (parameters) -> return-type { definition of method }

Why we use lambda expression in c++?

C++ Lambda expression allows us to define anonymous function objects (functors) which can either be used inline or passed as an argument. Lambda expression was introduced in C++11 for creating anonymous functors in a more convenient and concise way.


2 Answers

Lambda call operator member functions are const by default. If you want a mutable call operator, say mutable:

auto fn = [=]() mutable {
//              ^^^^^^^
    v.push_back("world");
};

Having const be the default forces you to be explicit about the fact that you mean to capture a copy of the vector and mutate that copy, rather than the original vector v.

By contrast, variables that are captured by reference can be mutated by const-qualified member functions:

auto fn = [&]() {
//        ^^^
    v.push_back("world");  // modifies original "V"!
};

(This is essentially because const T is the same as T when T = U &; there are no "constant references" in C++.)

like image 115
Kerrek SB Avatar answered Oct 26 '22 23:10

Kerrek SB


capture by value is const use the keyword mutable (doesn't change the original vector):

auto fn = [=]() mutable {
    v.push_back("world");
};

or by reference (changes the original vector):

auto fn = [&]() {
    v.push_back("world");
};
like image 33
Andreas DM Avatar answered Oct 27 '22 00:10

Andreas DM