简体   繁体   中英

Non-const lambda capture in const method

#include <iostream>
#include <functional>

class Blub {
public:
    int i = 0;
    std::function<void()> create() const {
        return [this]() {
            this->i = 100;
        };
    }
};

int main() {
    Blub blub = Blub();
    blub.create()();
    std::cout << blub.i << std::endl;
    return 0;
}

I know that this is captured as const inside the lambda, because the method is marked const. Is there still a way, aside from removing the constness of the method, to archive that i can modify member variables inside the lambda function?

Adding mutable keyword is not working.

You can declare the member variable i as mutable , so that it could change even if the object is declared as const :

class Blub {
public:
    mutable int i = 0;
//  ^^^^^^^
    std::function<void()> create() const {
        return [this]() {
            this->i = 100;
        };
    }
};

Live here .

You can do the following workaround :

class Blub {
public:
    int i = 0;
    std::function<void()> create() const {
        return [my_this=const_cast<Blub*>(this)]() {
            my_this->i = 100;
        };
    }
};

but it is misleading to change a data member in a function which is actually marked as const so I wouldn't suggest designing your class in that way.

Check it out live .

NB It is worth to mention that const_cast is safe to use only if it's used for casting a variable that was originally non- const . If the variable is originally const , using const_cast could result in Undefined Behavior. So, in the following code (which the OP provided):

int main() {
    Blub blub = Blub();
    blub.create()();
    std::cout << blub.i << std::endl;
    return 0;
}

it is safe to use const_cast because object is originally made non- const . However, if we make it const like in the following code:

int main() {
    const Blub blub = Blub();
    blub.create()();
    std::cout << blub.i << std::endl;
    return 0;
}

it will result in an Undefined Behavior.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM