簡體   English   中英

移動構造函數應該采用const還是非const rvalue引用?

[英]Should a move constructor take a const or non-const rvalue reference?

在一些地方,我已經看到了復制和移動構造函數的推薦簽名,如下所示:

struct T
{
    T();
    T(const T& other);
    T(T&& other);
};

復制構造函數采用const引用,移動構造函數采用非const rvalue引用。

據我所知,這使我無法在從函數返回const對象時利用移動語義,例如下面的情況:

T generate_t()
{
    const T t;
    return t;
}

使用VC11 Beta對此進行測試,調用T的復制構造函數,而不是移動構造函數。 甚至使用return std::move(t); 復制構造函數仍然被調用。

我可以看到這是有道理的,因為t是const所以不應該綁定到T&& 在移動構造函數簽名中使用const T&&工作正常,並且有意義,但是你有問題,因為other是const,如果需要將它們排除在外,你不能將其成員歸零 - 它只會在所有成員是標量或具有正確簽名的移動構造函數。

它看起來像,以確保移動構造函數在一般情況下已經作出的唯一途徑t擺在首位非const,但我不喜歡這樣做- consting東西是好的形式,我不希望T的客戶知道他們不得不反對這種形式以提高性能。

所以,我想我的問題是雙重的; 首先,移動構造函數應該采用const還是非const rvalue引用? 第二:我在這種推理中是對的嗎? 我應該停止返回const的東西?

這應該是一個非const右值引用。

如果將對象放在只讀內存中,則無法從中竊取資源,即使其正式生命周期即將結束。 允許在C ++中以const創建的對象存在於只讀內存中(使用const_cast嘗試更改它們會導致未定義的行為)。

移動構造函數通常應該采用非const引用。

如果可以從const對象移動,通常意味着復制對象與從其“移動”對象一樣有效。 此時,擁有移動構造函數通常沒有任何好處。

你也是正確的,如果你有一個你可能想要移動的變量,那么它將需要是非const的。

據我所知,這就是Scott Meyers改變了他對C ++ 11函數中返回類類型對象的建議的原因。 通過const限定值返回對象確實可以防止無意中修改臨時對象,但它也會禁止從返回值移動。

移動構造函數應該采用const還是非const rvalue引用?

它應該采用非const rvalue引用 rvalue引用首先在const表單中沒有意義,因為你想要修改它們(在某種程度上,你想要“移動”它們,你想要自己的內部)。

此外,它們被設計為在沒有 const的情況下使用,我相信const rvalue參考的唯一用途是Scott Meyers在本次演講中提到的非常神秘的東西(從時間42:20到44:47)。

我在這種推理中是對的嗎? 我應該停止返回const的東西?

我認為這是一個太普遍的問題。 在這種情況下,我認為值得一提的是, std::forward功能將保留rvalue-ness和lvalue-ness以及const-ness,並且它還可以避免創建臨時函數,因為正常函數會返回任何事情都傳遞給它。

這種返回也會導致右值引用被“損壞”到左值引用中,並且通常不需要它,因此,使用上述功能完美轉發可以解決問題。

話雖這么說,我建議你只看一下我發布鏈接的話題。

除了在其他答案中所說的內容之外,有時還有移動構造函數或函數接受const T&& 例如,如果將按值返回const對象的函數的結果傳遞給構造函數,則會調用T(const T&)而不是T(T&&) ,如下所示(參見下面的函數g )。

這是刪除接受const T&& for std::refstd::cref而不是接受T&&重載的原因。

具體而言,重載解析期間的優先順序如下:

struct s {};

void f (      s&);  // #1
void f (const s&);  // #2
void f (      s&&); // #3
void f (const s&&); // #4

const s g ();
s x;
const s cx;

f (s ()); // rvalue        #3, #4, #2
f (g ()); // const rvalue  #4, #2
f (x);    // lvalue        #1, #2
f (cx);   // const lvalue  #2

有關詳細信息,請參閱此文章

暫無
暫無

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

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