4

I wonder why this lambda function doesn't return the right answer:

int main()
{
    int a = 3, b = 7;
    [&]() ->void {(&a == &b) ? a : (a ^= b, b ^= a, a ^= b); };
    std::cout << a << " " << b;
    return 0;
}

It shows me 3 7 instead of 7 3

pfabri
  • 885
  • 1
  • 9
  • 25
  • 4
    Because you never call it. – bipll May 25 '20 at 09:01
  • I don't want to call it, I just want to swap a and b –  May 25 '20 at 09:02
  • 2
    If you define a function, and do not call it, nothing will happen. maybe you waste some memory but nothing more. So if your function should do something you HAVE to call it! – Klaus May 25 '20 at 09:03
  • 2
    `I don't want to call it, I just want to swap a and b` but if you want the code of the lambda to be executed you need to call the lambda. – t.niese May 25 '20 at 09:03
  • I thought the compiler will execute this function when it passes the line where the function is located –  May 25 '20 at 09:05
  • No, it won't, it creates a lambda function that can be called. If you want that the code in the lambda is directly executed, then don't wrap it in a lambda, just write `(&a == &b) ? a : (a ^= b, b ^= a, a ^= b);` instead of `[&]() ->void {(&a == &b) ? a : (a ^= b, b ^= a, a ^= b); };` – t.niese May 25 '20 at 09:07
  • What you are doing is abuse of lambda! Simply remove all the lambda stuff around and the functionality will be executed. A lambda is designed to define a functional object on the fly and pass it to another function. Define a lambda and call it direct is helping for nothing. – Klaus May 25 '20 at 09:08
  • 3
    We already have [`std::swap`](https://en.cppreference.com/w/cpp/algorithm/swap). – Jarod42 May 25 '20 at 09:21
  • @Ope "I don't want to run the code, I just need everything it does to be done." Well... – bipll May 25 '20 at 13:33

2 Answers2

3

You didn't call the lambda. You just declared an unnamed function object which is discarded immediately. You can call it as

[&]() ->void {(&a == &b) ? a : (a ^= b, b ^= a, a ^= b); } ();
//                                                         ^^

Then the function body will be evaluated and do what you expect.

LIVE

Roy2511
  • 938
  • 1
  • 5
  • 22
songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • why do you add () at the end, what's the meaning of that? –  May 25 '20 at 09:03
  • @Ope because lambda creates nameless functor. You need() to invoke it. – Tony Tannous May 25 '20 at 09:06
  • @TonyTannous, can you explain a little bit, what do you mean lambda overloads () –  May 25 '20 at 09:08
  • @Ope read [What is a lambda expression in c++11](https://stackoverflow.com/questions/7627098/what-is-a-lambda-expression-in-c11) the answers there should help you understand. – Tony Tannous May 25 '20 at 09:08
1

Defining a lambda does not implicitely call it.

You have to call it:

auto f = [&]() ->void {(&a == &b) ? a : (a ^= b, b ^= a, a ^= b); };
f();
Nicolas Dusart
  • 1,867
  • 18
  • 26
  • 1
    This is abuse of lambda! Why lambda is defined, stored, called? Simply execute the code and everything is fine without such obscure coding. – Klaus May 25 '20 at 09:09
  • @Klaus, the question shows a misconception that defining a lambda implicitely call it. What's the problem with my answer ? – Nicolas Dusart May 25 '20 at 09:10
  • OP asks explicitly: "I don't want to call it, I just want to swap a and b " So there is no deed to define, store, call a lambda. Simply execute the code in place. OP uses lambda without any need. Your answer continues the wrong coding instead of correct it, even f it is now working. But it still makes no sense do do it in this way! If it should make a bit sense of academic use of a lambda, it can be called inline by adding "()" at the end. But define/store/call is not what any experienced c++ developer will do in real code. See answer from songyuanyao – Klaus May 25 '20 at 09:12
  • 1
    Well, people may end up here because they have the same false assumption as the OP and the answer may still be helpul. The question is about lambdas, not about structuring code. – Nicolas Dusart May 25 '20 at 09:15
  • @Klaus, because you think that adding a "()" at the end skip the storage of the lamda ? This is purely equivalent (https://godbolt.org/z/3YHxn-, next time test before telling something wrong), but giving it a name before calling it is just more readable, especially for newcomers. I dont"t think you have any valuable source telling that any experienced C++ developer would'nt do that this way. – Nicolas Dusart May 25 '20 at 09:23
  • By giving it a name you bind it, thus it is stored. Lambda functions, by definition, are not meant to be bound to anything. They are throw-away functions. – pfabri May 25 '20 at 09:29
  • 1
    There is use cases where binding a lambda to a name is still useful. You can than define a lambda that is usable in mulitple parts of the same function with the ability to share the scope of the current function. – Nicolas Dusart May 25 '20 at 09:33
  • @NicolasDusart Okay, this last one about sharing the scope is convincing. But if you require all that then you're probably beyond the complexity threshold that lambdas are meant to solve already. – pfabri May 25 '20 at 09:36