Const reference parameter in lambda function

Viewed 204
#include <iostream>
#include <functional>

using Callback = std::function<void(const int)>;

int main() {
    Callback testCall = [](const int &num) {
        std::cout << "callback: " << num << " - " << &num << std::endl;
    };
    int num = 42;
    testCall(num);
    std::cout << "main:     " << num << " - " << &num << std::endl;
}

Possible output:

callback: 42 - 000000B19197F618
main:     42 - 000000B19197F694

As you can see, even if i assign a lambda function which takes the parameter by reference it still uses a copy.

Is that correct?

If yes, why does it still compile? Why is there at least not a warning about the discrepancy between the Callback declaration parameters and the assigned lambda. (const int &num vs const int num)

When not usingconst it does not compile.

PS. if you find a better title, feel free to edit.

1 Answers

This is because testCall is a functor object that catch its parameter by copy and then call the lambda on it.

Try:

Callback f = [](const int &num) {
        std::cout << "callback: " << num << " - " << &num << std::endl;
};

int main() {
        int num = 999;
        std::cout << "callback: " << num << " - " << &num << std::endl;
        f(num);
        [](const int &num) {
                std::cout << "callback: " << num << " - " << &num << std::endl;
        }(num);
}

you will see something like:

callback: 999 - 0x7ffeed60a9bc
callback: 999 - 0x7ffeed60a994
callback: 999 - 0x7ffeed60a9bc    

which means that callBack is not the function by itself but an indirection to the function. And there is no problem regarding types...

Answer to this may helps you to understand what happens under the hood: How std::function works

Related