包含lambdas的struct,它通过引用修改值

时间:2016-02-08 08:28:58

标签: c++ lambda

这是一个简单的程序,它使用value_control结构来存储修改整数变量的lambda:

#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;
}

输出:

122
123

这是一个将value_control创作抽象为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;
}

该程序的版本与第一版的行为不同:

-19620773
178

有关如何编写make_numeric_control以使第二个版本像第一个版本一样工作的任何建议吗?

1 个答案:

答案 0 :(得分:4)

这是因为您通过引用以及change捕获var归因于[&]捕获说明符。当change退出时,make_numeric_control将被破坏,因此在封闭内部将是一个悬空参考。

您可以通过引用var和值change来获取此值:

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