2
class TestGetStr {
public:
    string a;
    string getString() {
        return a;
    }
};

void acceptConstString(const string & a) {
    std::cout << a << std::endl;
}

int main(int argc, const char * argv[]) {
    
    auto testGetStr = TestGetStr();

    acceptConstString(testGetStr.getString()); //compile ok

    auto testaaa = [testGetStr](){

//compile error 'this' argument to member function 'getString' has type 'const TestGetStr', but function is not marked const        
acceptConstString(testGetStr.getString());
    };
    

Difference between normal call and lambda capture?

The normal call can compile, but the lambda call can't compile.

And Why? Thanks for more detail.

Learing
  • 559
  • 4
  • 13
  • 1
    Lambdas are `const` by default. You need to explicitly mark it as `mutable` - `auto testaaa = [testGetStr]() mutable {...}`. Or, better, mark `getString()` as `const`. – Yksisarvinen Mar 08 '21 at 08:50

1 Answers1

2

You can add mutable qualifier.

auto testaaa = [testGetStr]() mutable {
//                            ^^^^^^^
    acceptConstString(testGetStr.getString());
};

Otherwise the operator() of the lambda is const-qualified, and then can't call non-const member functions on the captured object.

  • mutable: allows body to modify the objects captured by copy, and to call their non-const member functions

Unless the keyword mutable was used in the lambda-expression, the function-call operator is const-qualified and the objects that were captured by copy are non-modifiable from inside this operator().

PS: Or better to make TestGetStr::getString() const member function.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405