2017-07-11 23 views
0

返回在下面的代碼我有修改了兩本很貴對模仿對象的功能,我試圖逃脫,沒有輸出參數的std ::領帶和對象的生命週期中的元組

struct FatThing {/* some big data members here*/}; 

    auto processFatThings(FatThing ft1, FatThing ft2)-> std::tuple<FatThing, FatThing> { 
     // do smth with those two 
     return std::make_tuple(move(ft1), move(ft2)); 
    } 

    auto useProcessFatThings()-> void { 
     FatThing ft1, ft2; 
     std::tie(ft1, ft2) = processFatThings(move(ft1), move(ft2)); // dangling references? 
    } 

我我現在有點困惑,因爲編譯器不會發出任何警告,sanitizers和memcheck是乾淨的,代碼工作。但!!!是不是在std :: tie這裏創建的懸掛引用?

+0

爲什麼你認爲涉及懸掛引用?你沒有在任何地方使用引用,既不在函數參數中,也不在你的返回類型中。 – pschill

回答

1

不,沒有懸掛引用。 ft1ft2將被分配給從processFatThings

返回值的各要素例如見下面的代碼

#include <iostream> 
#include <tuple> 
#include <type_traits> 

using std::cout; 
using std::endl; 

class Something { 
public: 
    Something() { 
     cout << __PRETTY_FUNCTION__ << endl; 
    } 
    Something(Something&&) { 
     cout << __PRETTY_FUNCTION__ << endl; 
    } 
    Something(const Something&) { 
     cout << __PRETTY_FUNCTION__ << endl; 
    } 
    ~Something() { 
     cout << __PRETTY_FUNCTION__ << endl; 
    } 
    Something& operator=(const Something&) { 
     cout << __PRETTY_FUNCTION__ << endl; 
     return *this; 
    } 
}; 

int main() { 
    Something one, two; 
    std::tie(one, two) = std::make_tuple(Something(), Something()); 
} 
這裏 https://wandbox.org/permlink/iG1qIJ2VKL4bljPM

這裏

現場演示中,你會看到有4層結構,對應於one,twomake_tuple的兩個參數。

然後兩個移動結構爲make_tuple

然後有兩個副本分配。這是這裏的關鍵部分。將Something對象複製到與「std::tie」「綁定」的任何對象。

所以沒有懸掛引用,你會得到副本/動作!

+0

那麼,如果你添加了移動任務,它將使用它。我對它的工作原理還是有點困惑,但現在感覺好多了:)。謝謝! – Slava

1

這裏沒有跳轉引用。 ft1ft2是值,我們將它們綁定到引用,並且ft1ft2(在塊的末尾過期)的壽命超過引用(在行末尾過期)。

然而,這:

auto ftings = processFatThings(move(ft1), move(ft2)); 
    FatThing& ft1 = std::get<0>(ftings); 
    FatThing& ft2 = std::get<1>(ftings); 

是略好,因爲它消除此舉建設。它也排隊什麼

auto[ft1,ft2] = processFatThings(move(ft1), move(ft2)); 

在C + + 17中。

注意,如果FatThing有大數據成員它,而不是通過擁有move於事無補。 10億個元素的陣列需要10億個單位的時間才能移動。與此同時,一個數據成員是10億個元素的向量,比複製要快得多。 (Vector擁有它的緩衝區,它不會將其緩衝區保存在其中)