簡體   English   中英

一對向量構造函數:初始化列表與顯式構造

[英]Pair of vector constructors: initializer list vs explicit construction

我用兩種方式調用std::pair<vector<int>, int>構造函數:

  • 傳入初始化列表
  • 傳入一個顯式向量(r值)。

出於某種原因,初始化列表版本會復制(並銷毀一個)。
這是我的最小代碼示例:

auto dummy() {
    return pair<vector<int>, int>{ {1,2,3,4,5}, 1};
}

auto dummy1() {
    return pair<vector<int>, int>{ vector{1,2,3,4,5}, 1};
}

auto dummy2() {
    return optional<vector<int> > { {1,2,3,4,5} };
}

檢查編譯器資源管理器后,我發現初始化列表dummy()版本調用operator new兩次,並delete一次。 dummy2()既沒有顯式構造版本dummy1()也沒有類似的std::optional構造函數。 我不指望這種行為。 有誰知道為什么? 我也和clang一起檢查過。

問題來自std::pair構造函數和模板參數推導/重載解析:

pair( const T1& x, const T2& y ); // (1)

template< class U1, class U2 >
pair( U1&& x, U2&& y );           // (2)

請注意,至少有一個“缺失”構造函數:

pair( T1&& x, T2&& y );           // (3)

當您對第一個參數使用list-initialization時,所選的構造函數不是(2) (使用U1 = std::initializer_list<int> )但是(1) 1 因此,您需要構造一個臨時的std::vector<int> ,它作為const reference引用到(1) ,它必須進行復制。

您可以通過以下任一方式憑經驗確認:

  • 使用上面提到的第三個構造函數創建自己的pair - 在這種情況下,將選擇(3) ,並移動臨時vector ;
  • 在構造std::pair顯式構造一個std::initializer_list<int>
pair<vector<int>, int>{ std::initializer_list<int>{1,2,3,4,5}, 1 };

另一方面, std::optional作為單個模板化構造函數:

template < class U = value_type >
constexpr optional( U&& value );

...但是U有一個默認值,這使得這個構造函數成為重載決策的有效候選者。


1當您調用pair{ {1,2,3,4,5}, 1 }U1位於(2) [temp.deduct.type]#5.6中的非推導上下文中,因此扣除失敗,這就是為什么(1)被選中。

暫無
暫無

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

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