我正在尝试将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行不同,尽管它们都引用了同一个对象。唯一的区别是添加了另一层间接。)< / p>
答案 0 :(得分:4)
这是错误的:
auto temps = StoreSaved(
/* This temporary value dies at the last semicolon! */
SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;})
);
StoreSaved
然后有一个指向不存在对象的指针。使用它是UB。
答案 1 :(得分:1)
正如其他人已经指出的那样,问题是在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()
,因为您不再处理指针。