Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Refresh" a lambda object

Tags:

c++

c++11

lambda

I created my lambda like so:

int i = 0;
auto gen_lam = [=]() mutable -> int {return ++i;};

It effectively counts the number of times it has been called, because it stores the captured i. Is there a way to "reconstruct" the object so it starts out with the initial value of i?

Something along the lines of:

decltype(gen_lam) gen_lam2;

such that the following code outputs 1 1 instead of 1 2

std::cout << gen_lam() << std::endl;

decltype(gen_lam) gen_lam2;

std::cout << gen_lam2() << std::endl;
like image 882
TeaOverflow Avatar asked Sep 23 '14 13:09

TeaOverflow


2 Answers

Simply done, wrap your lambda-creation in a lambda, which you can call whenever you need the inner lambda re-initialized:

auto wrap_lam = [](int i) {return [=]() mutable {return ++i;};}
auto gen_lam = wrap_lam(0);
auto gen_lam2 = wrap_lam(0);

Or just make a copy to preserve the state whenever you want:

auto gen_lam = [=]() mutable -> int {return ++i;};
const auto save = gen_lam;

If you only ever want a full reset, naturally save as a const object first.

like image 152
Deduplicator Avatar answered Sep 29 '22 15:09

Deduplicator


I think what you want could be done by having a generator that captures different counters.

#include <iostream>
#include <functional>

using namespace std;

int main()
{
    int i = 0;
    int j = 0;

    auto lambda_generator = [](int& val) {
        auto var = [=]() mutable -> int {return ++val;};
        return var;
    };

    auto counter1 = lambda_generator(i);

    std::cout << counter1() << std::endl;

    auto counter2 = lambda_generator(j);

    std::cout << counter2() << std::endl;

}

If "reset" means you want a different counter.

like image 42
IdeaHat Avatar answered Sep 29 '22 14:09

IdeaHat