簡體   English   中英

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;})
                );

然后, StoreSaved具有指向不存在對象的指針。 使用它是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() ,因為您不再處理指針。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM