如何从lambda-functor的体中增加变量?

时间:2016-03-31 10:55:00

标签: c++ c++11 lambda c++14

我试图从lambda表达式中增加一个局部变量:

#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

但是出现了以下错误:

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++; 

             ^

在c ++ 11/14中是否有一些解决方法?

4 个答案:

答案 0 :(得分:7)

max_len=30在非可变lambda中被副本捕获时无法修改。

您可以通过引用捕获max_len=254

temp

答案 1 :(得分:4)

如果要按值捕获变量并对其进行修改,则需要标记lambda mutable

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

这允许主体修改value捕获的参数,并调用它们的非const成员函数

答案 2 :(得分:3)

这是C ++ 14,所以你可以简化你的lambda 也就是说,这些是一些有效的解决方案(我假设你想要改变原始变量的值,而不是它的副本):

  • 通过引用捕获:

    [&temp]() { temp++; }();

(你必须保证temp的生命周期结果是lambda之一

  • 来回复制:

    temp = [temp = temp]() mutable { return ++temp; }();

(不要求你保证temp的生命周期结果是lambda之一

  • 来回移动:

    temp = [temp{std::move(temp)}]() mutable { temp++; return std::move(temp); }();

(不要求你保证temp的生命周期结果是lambda之一

等等......

答案 3 :(得分:2)

你的意思是&#34;本地变量&#34;有点模棱两可。

  1. 要增加foo temp,您需要capture by reference,因此您的lambda将如下所示:[&temp] { temp++; }
  2. 要增加lambda temp,您需要use the mutable keyword,所以您的lambda将如下所示:[temp]() mutable { temp++; }
  3. 您似乎不太可能尝试 2 ,因为您所做的任何更改都会在返回lambda时丢失,因为它没有返回任何内容。并且,在您给出的示例中,您不再在lambda中使用temp

    假设您正在尝试 1 ,您需要确保T不是参考,而不是const。这些例子中的任何一个都会让你遇到麻烦:

    const auto t = 1;
    foo(t);
    

    auto& t = bar;
    foo(t);
    

    要避免这两种情况,您应该使用decay_t定义foo&#39; temp

    decay_t<T> temp{};