[英]Pair of vector constructors: initializer list vs explicit construction
我用兩種方式調用std::pair<vector<int>, int>
構造函數:
出於某種原因,初始化列表版本會復制(並銷毀一個)。
這是我的最小代碼示例:
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.