我试图从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;
}
但是出现了以下错误:
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中是否有一些解决方法?
答案 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;有点模棱两可。
foo
temp
,您需要capture by reference,因此您的lambda将如下所示:[&temp] { temp++; }
temp
,您需要use the mutable
keyword,所以您的lambda将如下所示:[temp]() mutable { temp++; }
您似乎不太可能尝试 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{};