Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to increment a variable from lambda-functor's body?

I tried to increment a local variable from lambda expression:

#include <iostream>

template<typename T>
T foo(T t){
    T temp{};
    [temp]() -> void { 
        temp++; 
    }();
    return temp;
}

int main()
{
    std::cout<< foo(10) << std::endl;
}

DEMO

But got the following error:

main.cpp: In instantiation of 'foo(T)::<lambda()> [with T = int]':

main.cpp:6:6:   required from 'struct foo(T) [with T = int]::<lambda()>'

main.cpp:8:6:   required from 'T foo(T) [with T = int]'

main.cpp:14:23:   required from here

main.cpp:7:13: error: increment of read-only variable 'temp'

         temp++; 

             ^

Is there some workaround about that in c++11/14?

like image 416
St.Antario Avatar asked Mar 31 '16 10:03

St.Antario


People also ask

How do you increment a variable in lambda expression in Java?

If you really need to increment a counter from within a lambda, the typical way to do so is to make the counter an AtomicInteger or AtomicLong and then call one of the increment methods on it. You could use a single-element int or long array, but that would have race conditions if the stream is run in parallel.

Can we change the lambda expression variable data?

Yes, you can modify local variables from inside lambdas (in the way shown by the other answers), but you should not do it.

How are variables used outside of lambda expression?

Because the local variables declared outside the lambda expression can be final or effectively final. The rule of final or effectively final is also applicable for method parameters and exception parameters. The this and super references inside a lambda expression body are the same as their enclosing scope.

Why lambda function 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

temp cannot be modified when it's captured by copy in a non-mutable lambda.

You could capture temp by reference:

template<typename T>
T foo(T t){
    T temp{};
    [&temp]() -> void { 
        temp++; 
    }();
    return temp;
}
like image 156
songyuanyao Avatar answered Sep 24 '22 01:09

songyuanyao


If you want to capture a variable by value and modify it, you need to mark the lambda mutable:

[temp]() mutable -> void {
//       ^^^^^^^ 
    temp++; 
}();

This allows the body to modify the parameters captured by value, and to call their non-const member functions

like image 43
TartanLlama Avatar answered Sep 23 '22 01:09

TartanLlama