dharmatech February 2016

struct containing lambdas which modify values via reference

Here's a simple program which uses a value_control struct to store lambdas which modify an integer variable:

#include <iostream>
#include <functional>

struct value_control
{
    std::function<void(void)> increase;
    std::function<void(void)> decrease;
};

int main()
{   
    auto a = 123;

    value_control a_control{ [&]() { a += 1; }, [&]() { a -= 1; } };

    a_control.decrease(); std::cout << a << std::endl;

    a_control.increase(); std::cout << a << std::endl;
}

Output:

122
123

Here's a version which abstracts out the value_control creation into make_numeric_control:

#include <iostream>
#include <functional>

struct value_control
{
    std::function<void(void)> increase;
    std::function<void(void)> decrease;
};

int main()
{   
    auto make_numeric_control = [](int& var, int change)
    {
        return value_control
        {
            [&]() { var += change; },
            [&]() { var -= change; }
        };
    };

    auto a = 123;

    auto a_control = make_numeric_control(a, 1);

    a_control.decrease(); std::cout << a << std::endl;

    a_control.increase(); std::cout << a << std::endl;
}

This version of the program does not behave like the first:

-19620773
178

Any suggestions for how to write make_numeric_control such that it the second version works like the first version?

Answers


TartanLlama February 2016

This is because you capture change by reference as well as var due to the [&] capture specifier. change will be destructed when make_numeric_control exits, so inside the closure it will be a dangling reference.

You can fix this by capturing var by reference and change by value:

    return value_control
    {
        [&var, change]() { var += change; },
        [&var, change]() { var -= change; }
    };

Post Status

Asked in February 2016
Viewed 2,185 times
Voted 11
Answered 1 times

Search




Leave an answer