簡體   English   中英

將std :: forward_as_tuple()結果傳遞給可能從該對象的右值引用成員移出的多個函數?

[英]Passing std::forward_as_tuple() result to multiple functions that may move from that object's rvalue-reference members?

編輯:我想我問的最可能的用例是當創建一個從std::forward_as_tuple()接收元組右值引用的函數時。

出現此問題的原因是因為我正在檢查傳遞給構造函數初始值設定項的對象的成員 ,以查看它們是否是右值引用(我很樂意告訴我這是錯誤的錯誤,錯誤的……希望后面跟一個避免在將來避免這種情況的經驗法則,但這就是提示問題的原因)。 我想到,在稍微不同的上下文中,我可能最終將具有右值引用成員的對象交給我可能控制或可能不控制的多個函數(或函數對象),這些對象確實可以從那些成員中移出。

template<typename... Args>
void my_func(std::tuple<Args...>&& tup) {

    //if tup's members are rvalue references,
    //and this function moves guts from tup members, then...
    func_i_dont_control(tup); 

    //what happens here if moves are done on the same members?
    another_func_i_dont_control(std::move(tup));
}

我看過使用右值引用成員嗎? ,以及有關右值引用成員的其他一些討論,但是我不能完全確定這一點。

我不僅在詢問會發生什么,而且還詢問這種情況是否應該甚至可能發生,以及在傳遞包含右值引用成員的對象時要記住哪些關鍵規則。

元組和可變參數模板的使用似乎從問題的角度出發,因此讓我重新表述一下:

void func(std::unique_ptr<Foo>&& foo) {
  std::unique_ptr<Foo> bar1(std::move(foo));
  std::unique_ptr<Foo> bar2(std::move(foo));
}

這里會發生什么? 好吧, bar2始終包含一個空指針(而bar1可能取決於foo的原始值)。

沒有未定義的行為,因為精確出於安全原因,移動構造函數應使對象處於所需的可用狀態引用狀態。 因此,您可以使用從移出的對象,但是其狀態可能不會很有趣:它甚至不必等同於默認的構造狀態,它可以只是陳舊的狀態。

在此代碼中, func_i_dont_control無法靜默竊取該參數。 只有右值綁定到右值引用,而命名變量不是右值。 您的代碼無法編譯,或者func_i_dont_control (具有重載)不使用移動語義。

為了使func_i_dont_control有機會竊取元組(將元組綁定到右值引用),必須使用std::move(tup)將其顯式轉換為右值。

(使用左值引用的函數不應離開它,否則我們真的無法判斷會發生什么。)


編輯但是問題似乎不是關於元組本身,而是它的成員。 同樣,這些成員將不是右值,因此func_i_dont_control將需要顯式移動它們。 我認為這樣做沒有“道德權利” *,除非它將整個元組作為右值接收,這在您的函數中不會發生。

*使用移動語義時,您必須遵循某些准則。 基本上,您可以將任何內容強制轉換為rvalue並從其移走,如果您正在處理lvalue或rvalue引用都沒有關系。 只要您遵循這些准則,移動語義就可以正常工作。 如果您開始無視這些准則將事物投射到右值,則對象將在函數調用等之后開始消失。

暫無
暫無

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

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