C++ 如何从lambda函子';谁的身体?
我试图从lambda表达式中增加一个局部变量:C++ 如何从lambda函子';谁的身体?,c++,c++11,lambda,c++14,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; } #包括 模板
#include <iostream>
template<typename T>
T foo(T t){
T temp{};
[temp]() -> void {
temp++;
}();
return temp;
}
int main()
{
std::cout<< foo(10) << std::endl;
}
#包括
模板
T-foo(T-T){
T温度{};
[temp]()->void{
temp++;
}();
返回温度;
}
int main()
{
std::couttemp
在不可变lambda中通过复制捕获时,无法修改
您可以通过引用捕获temp
:
template<typename T>
T foo(T t){
T temp{};
[&temp]() -> void {
temp++;
}();
return temp;
}
模板
T-foo(T-T){
T温度{};
[&temp]()->void{
temp++;
}();
返回温度;
}
如果要按值捕获变量并对其进行修改,则需要标记lambda可变值
:
[temp]() mutable -> void {
// ^^^^^^^
temp++;
}();
这允许主体修改由值捕获的参数,并调用它们的非常量成员函数您所说的“局部变量”有点含糊不清
要增加foo
的temp
,您需要这样做,因此您的lambda将如下所示:[&temp]{temp++;}
要增加lambda的temp
,您需要这样做,使lambda看起来像:[temp]()可变{temp++;}
您似乎不太可能尝试执行2,因为您所做的任何更改都将在lambda返回时丢失,因为它不会返回任何内容。并且,在您给出的示例中,您不会在lambda中进一步使用temp
因此,假设您试图执行1,您需要确保T
不是引用,也不是const
。以下任一示例都会给您带来麻烦:
const auto t = 1;
foo(t);
或
为了避免这两种情况,您应该使用以下内容定义foo
的temp
:
衰变温度{};
它是C++14,因此您可以简化lambda。
也就是说,这些是一些有效的解决方案(我假设您希望更改原始变量的值,而不是它的副本的值):
- 通过引用捕获:
template<typename T>
T foo(T t){
T temp{};
[&temp]() -> void {
temp++;
}();
return temp;
}
[&temp](){temp++;}();
(您必须保证temp
的寿命与lambda的寿命相同)
- 来回复制:
temp=[temp=temp]()可变{return++temp;}();
(不要求您保证temp
的寿命与lambda的寿命相同)
- 来回移动:
temp=[temp{std::move(temp)}]()可变{temp++;返回std::move(temp);}();
(不要求您保证temp
的寿命与lambda的寿命相同)
等等…它会修改复制的一个,而与外部的temp
无关吗?@songyuanyao:是的。:-@songyuanyao是的,它仍然是一个附带的值捕获,不管它的易变性如何。我明白了,谢谢。也许更值得一提的是,我认为它与OP的初衷相冲突。看到有人使用C,我很高兴++14的捕获初始值设定项,所以有一个+1。但是由于lambda的使用方式,我认为这里不需要C++11语法以外的任何东西。@JonathanMee我知道,你是对的,但这是一个使用它们的好机会!!:-)老实说,我想要C++14给我们的是在捕获列表中定义临时值的能力,比如[int i{}]{return++i;}
虽然已经讨论过了,但它在C++17中仍然不可用:(@JonathanMee为什么不能在lambda的主体中定义它们呢?我不完全理解这一点,抱歉…@JonathanMee:FWIW,[i=int{}])可变的{return i;}
工作得很好。例如,我觉得我没有领会你的意思;-]
auto& t = bar;
foo(t);
decay_t<T> temp{};