2017-06-04 221 views
2

thing爲默認構造和移動構造類型。考慮以下兩個初始化:默認初始化與默認構建值的初始化初始化

thing t1;   // (1) 
auto t2 = thing{}; // (2) 
  • (1)默認構造t1

  • (2)默認構建thing類型的臨時表並將其移至t2

在何種情況下,(2)中的移動將被消除?

在現代風格的C++初始化中,類型通常根本不出現或出現在右側。例如:

auto copy = vec;        // Type doesn't appear 

auto p_derived = std::make_unique<derived>(); // Type appears naturally on the right 

// Putting the type on the right here makes it explicit that the upcast is intended 
auto p_base = std::unique_ptr<base>{ std::make_unique<derived>() }; 

使用(2)將與這些樣式一致,而使用(1)則不會。

另外,當使用(1)long typename時,變量名稱顯示在右側。當使用(2)時,無論類型名稱的長度如何,變量名稱同樣適用。

這是否意味着(2)爲了一致性而優於(1)?

+0

沒有關係,反正複製elsiion。 –

回答

2

在何種情況下,(2)中的移動將被消除?

當編譯器選擇退出。這實際上總是在現代編譯器上。但是,在C++ 11(也不是C++ 14)中沒有保證副本的省略。

使用(2)將與這些樣式一致,而使用(1)則不會。

這是否意味着(2)爲了一致性而優於(1)?

爲了一致性的緣故,一致性幾乎沒有什麼優勢。

理解爲什麼類型在您的示例中是正確的,以及爲什麼(這個意思是)auto存在是有用的。該類型在右側,因爲它在模板實例化中需要。還有一種類型也必須在左側也有聲明的語法。該類型也是右手錶達式的返回類型,因此引入了auto以允許從該表達式中扣除。這是有利的,因爲我們避免了類型的脆弱重複。

(1)沒有重複,因此在引入auto時沒有重複刪除優勢。沒有右手錶達,也沒有必要介紹一個。 (2)具有不必要的額外樣板,並且可移動類型的附加要求。

此外,當使用(1)與long typename時,變量名稱顯示在右側。當使用(2)時,無論類型名稱的長度如何,變量名稱同樣適用。

在我看來,這是一個弱的論點。你應該避免不必要的長typenames反正,但如果你堅持一個,你可以簡單地將它們放在不同的行:

thing_with_extra_long_type_name_for_some_reason<omg_it_doesnt_end> 
    t1; 
3

哪一個更好是意見問題。我不會權衡,這不是什麼意思。

每個支持C++ 11的現代編譯器都會忽略這種移動,除非您傳遞顯式編譯器標誌以避免不必要的東西。

在C++ 17中,沒有移動到elide; thing{}是一個prvalue,而prvalues不是C++ 17中的對象,而是創建對象的指令(可以實例化一個匿名臨時對象,但在本例中不是)。

auto x =prvalue;語句會導致使用的prvalue用以建構x