c++11通过值lambda捕获,生成错误的值
c++11 capture-by-value lambda producing wrong value
我正试图将lambda存储在涉及多个间接层的对象系统中。我使用g++4.7.1。
根据我构造(等效)对象的确切方式,lambda的值可能正确,也可能不正确。
代码:
#include <iostream>
#include <functional> // used for std::function
using namespace std; // TODO nope
typedef function<int()> intf;
struct SaveLambda {
const intf func;
SaveLambda(const intf& _func) : func(_func) {}
};
struct StoreSaved {
const SaveLambda* child;
StoreSaved(const SaveLambda& _child) : child(&_child) {
cout << "Before returning parent: " << child->func() << endl;
}
};
int main() {
const int ten = 10;
auto S = SaveLambda([ten](){return ten;});
cout << "No indirection: " << S.func() << endl << endl;
auto saved = StoreSaved(S);
cout << "Indirection, saved: " << saved.child->func() << endl << endl;
auto temps = StoreSaved ( SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;}) );
cout << "***** what. *****" << endl;
cout << "Indirection, unsaved: " << temps.child->func() << endl;
cout << "***** what. *****" << endl << endl;
cout << "ten still lives: " << ten << endl;
}
编译为g++ -std=c++11 -Wall -o itest itest.cpp
并运行:注意输出的一行具有不同的值。
我做错了什么?我认为按价值捕获会,嗯,按价值捕获。(最令人不安的是,StoreSaved中的打印(第15行)产生了正确的值,这与第34行不同,尽管它们都引用了同一个对象。唯一的区别是增加了另一层间接性。)
这是错误的:
auto temps = StoreSaved(
/* This temporary value dies at the last semicolon! */
SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;})
);
CCD_ 2有一个指向不存在对象的指针。使用它是UB。
正如其他人已经指出的,问题是在temps
中,您以指向不存在的SaveLambda
结构的指针结束,因为它是临时的。
您可以在StoreSaved中使用SaveLambda结构而不是指针来保存副本:
struct StoreSaved {
const SaveLambda child;
StoreSaved(const SaveLambda& _child) : child(_child) {
cout << "Before returning parent: " << child.func() << endl;
}
};
您还必须将所有的child->func()
更改为child.func()
,因为您不再处理指针了。
相关文章:
- 如何将strftime中的格式错误作为异常捕获
- 由cin中的字符串中未捕获空白引起的分割错误
- 通过实用程序 fn 将捕获的 lambda 传递给 C 样式回调 - 错误
- 使用 Vivek 的 Vcam / 捕获源过滤器构建/链接错误
- 我可以使用 try catch 语句来捕获任何错误而不是具体错误吗?
- 为什么访问我的引用捕获变量会导致我的 lambda 函数出现段错误?
- C++带有 while 语句范围捕获的 if 语句中的错误
- 组合 lambda 捕获时出现编译错误
- 捕获雨水:蛮力方法中的错误
- WM_MOUSEMOVE GET_X_LPARAM和GET_Y_LPARAM捕获错误的坐标
- 关于 ocilib 错误处理的问题,如何使用 ocilib 正确捕获日志错误?
- std::正则表达式捕获组语法错误
- "this" Lambda 捕获的是不正确的。海湾合作委员会编译器错误?
- 仅捕获异常就可以检测所有二进制文件在C 中读取错误是否足够
- C++ 使用生成文件捕获框架'multiple definition'链接器错误
- 在Python中编译C 程序时,请尝试捕获OS错误
- 在绑定中捕获 fortran 运行时错误和信号C++
- 捕获音频时出现 OpenAL 错误
- 通过分配c内存错误捕获c++异常
- 如何在for循环中进行错误捕获