在 C++14 中使用通用 lambda 和自动返回类型特征获得不同的结果
Different results obtained by using generic lambdas and automatic return type feature in C++14
我正在尝试使用C++在python中实现这一段高阶函数:
def add1(x):
def helper():
nonlocal x
x += 1
return x
return helper
以下是我创建的三个版本:
#include <iostream>
#include <functional>
using namespace std;
function<int(void)> add1_v1(int x) {
function<int(void)> g = [&x]() {return ++x;};
return g;
}
auto add1_v2(int x) {
function<int(void)> g = [&x]() {return ++x;};
return g;
}
auto add1_v3(int x) {
auto g = [&x]() {return ++x;};
return g;
}
int main() {
auto a = add1_v1(100);
auto b = add1_v2(100);
auto c = add1_v3(100);
for(int i = 0; i < 3; ++i) {
cout << a() << endl;
}
cout << "-------------------------------------------" << endl;
for(int i = 0; i < 3; ++i) {
cout << b() << endl;
}
cout << "-------------------------------------------" << endl;
for(int i = 0; i < 3; ++i) {
cout << c() << endl;
}
return 0;
}
输出为:
101
102
103
-------------------------------------------
4239465
4239466
4239467
-------------------------------------------
4201325
4201325
4201325
只有add1_v1符合我想要的。谁能解释一下我的原因?
原因是这是未定义的行为。
内部 lambda 通过引用捕获x
。
问题是,一旦add()
返回,它的参数就会被销毁,并且返回的 lambda 对已销毁对象的引用悬而未决。
lambda 必须按值捕获x
;在我看来,你在这里真正想做的是一个可变的 lambda:
auto add(int x) {
function<int(void)> g = [x]() mutable {return ++x;};
return g;
}
请注意,此方法在随后复制返回的 lambda 时具有某些含义;但只要返回的 lambda 在其剩余的生命周期中保持"在一个位置",生成的语义就可能是您所期望的。
所有这些都是格式不正确的,因为您在 lambda 中通过引用捕获x
,但x
是一个局部变量,当退出函数时会被销毁 add
,然后引用变得悬空,取消引用它会导致 UB,这意味着一切皆有可能; 即使是第一种情况似乎也可以正常工作。
不是答案,如果您将参数签名更改为 add1_v*(int&&x(,似乎所有版本的函数都可以正常工作
相关文章:
- 如何获取std::result_of函数的返回类型
- 奇怪的结构&GCC&clang(void*返回类型)
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 为什么与常规GCC不同,即使有"学究性错误",MinGW-GCC也能容忍丢失的返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 为什么返回类型中需要typename?C++
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 推导 std::vector::back() 的返回类型
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- 特征返回类型的 pybind11 问题
- 在 C++14 中使用通用 lambda 和自动返回类型特征获得不同的结果
- 用于测试 func(args) 格式是否正确以及是否具有必需的返回类型的特征