2

我正在尝试将 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 行不同,尽管它们都指的是同一个对象。唯一的区别是添加了另一层间接。)

4

2 回答 2

4

这是错误的:

auto temps = StoreSaved(
                /* This temporary value dies at the last semicolon! */
                SaveLambda([ten](){cout << "&ten: "<< &ten << endl; return ten;})
                );

StoreSaved然后有一个指向不存在对象的指针。使用它是UB。

于 2012-09-05T01:09:11.300 回答
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()to child.func(),因为您不再处理指针。

于 2012-09-05T04:39:21.557 回答