![](/img/trans.png)
[英]Returning by value or by rvalue reference from rvalue reference qualified member function?
[英]Difference between returning an rvalue reference and a value in && qualified functions
我最近看到了這個問題通過右值引用返回是否更有效? 並且注意到了評論鏈。 我正在評論鏈中尋找答案。
人們似乎說,在以下情況下,返回值應按右值引用而不是按值。 ( 通過右值引用返回是否更有效?並且在任何情況下, 返回右值引用 (&&)都是有用的嗎? )給出以下代碼
#include <iostream>
using namespace std;
class Something {
public:
Something() {
cout << "Something()" << endl;
}
Something(const Something&) {
cout << "Something(const Something&)" << endl;
}
Something(Something&&) {
cout << "Something(Something&&)" << endl;
}
};
class Maker {
public:
Something get_something() && {
return std::move(this->something);
}
const Something& get_something() & {
return this->something;
}
private:
Something something;
};
int main() {
auto maker = Maker{};
auto something_one = maker.get_something();
auto something_two = Maker{}.get_something();
return 0;
}
在Maker
類中使用右值引用返回類型和常規值定義第一個方法有什么區別? 運行上面的代碼可以按預期提供以下輸出(該移動發生在函數調用中,返回之后該移動被忽略)
Something()
Something(const Something&)
Something()
Something(Something&&)
當我更改代碼(即Maker
類中的第一個方法)以返回右值引用時,我仍然得到相同的輸出。 在這種情況下,為什么不只按價值返回?
當您以這種方式使用this
參考限定詞時,您必須問自己兩個問題:
std::move(object).funcname()
是什么意思? Typename().funcname()
是什么意思? 如果從函數返回一個值,則這兩個都將表示同一件事。 不管您執行什么操作來捕獲值,值都將是一個完整且與眾不同的對象,它是由存儲在對象中的一些內部數據移動構造而成的。
在第一種情況下, object
現在可能不再擁有數據。 在第二種情況下,這並不重要,因為該對象是臨時對象,此后已被銷毀。
如果從函數中返回&&
,那么它們將具有不同的含義。 即,#2表示“您的代碼已損壞”。
至於為什么您仍然想這樣做,即使它允許代碼損壞也是如此。 好吧,這與該問題的實際答案有關:這些東西是什么意思 ?
這就是我所指的。 std::get
基本上是tuple
的成員函數。 但是,如果將其傳遞給tuple&&
,則會得到T&&
返回,而不是T
為什么?
因為您正在訪問tuple
的成員 。
如果您具有struct
,則std::move(struct_object).x
也將是右值引用。 因此, std::get
對於tuple
行為與對struct
成員訪問的行為相同。 畢竟,這就是tuple
的全部要點:盡可能表現得像一個struct
。
這使您可以執行std::get<0>(std::move(tpl)).member
,這樣該member
仍將是右值引用。 因此,您可以從子對象移動而不會干擾對象的其余部分 ,這與您對任何其他右值引用成員的訪問一樣。
如果get
返回一個值,那么這樣做會大為不同。 無論我們如何處理返回值,它都將移出對象,而不會出現任何問題。 因此,如果我們只想移動該成員的子對象,那就太糟糕了。 原始對象失去了整個成員,而不僅僅是該成員的子對象。
當然,這不會改變以下事實:
auto &&x = SomeStruct().x; //This extends the temporary's lifetime
auto &&x = std::get<0>(SomeTuple(...)); //This gets a dangling reference.
這是語言的不幸限制。 但是,如果該函數是邏輯上的成員訪問,然后返回一個&&
從&&
勝任this
功能,而不是一個值是合理的選擇。
這完全取決於對您而言更重要的事情:安全性或與成員訪問器的正交性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.