[英]std::map of tuple to tuple and using emplace
考慮以下使用 g++ 7.0.1 (-std=c++17) 編譯的代碼:
#include <map>
#include <tuple>
int main()
{
// Create an alias for a tuple of three ints
using ThreeTuple=std::tuple<int,int,int>;
// Create an alias for a map of tuple to tuple (of three ints)
using MapThreeTupleToThreeTuple=std::map<ThreeTuple,ThreeTuple>;
MapThreeTupleToThreeTuple m;
// The following does NOT compile
m.emplace({1,2,3},{4,5,6});
// ..., and neither does this
m.emplace(std::piecewise_construct,{1,2,3},{4,5,6});
}
我原以為map::emplace()
的initializer_list
參數就足夠了,並且會導致按照指定將元組鍵插入到元組值關聯中。 顯然,編譯器不同意。
當然,顯式創建一個元組(即ThreeTuple{1,2,3}
而不僅僅是{1,2,3}
)並將其傳遞給map::emplace()
可以解決問題,但是為什么初始化程序不能列出直接傳遞給map::emplace()
,它會自動將它們轉發給元組構造函數?
AFAIK,在這種情況下,C++17 沒有任何變化。 正如 NathanOliver 和 Barry 所解釋的那樣, {1,2,3}
不能被推斷為具有任何類型,因此不能與模板參數匹配。 您必須為ThreeTuple
的構造函數提供ThreeTuple
推導類型的參數,即
m.emplace(std::piecewise_construct,
std::forward_as_tuple(1,2,3),
std::forward_as_tuple(4,5,6));
它調用構造函數
template<typename T1, typename T2>
template<typename... Args1, typename... Args2 >
std::pair<T1,T2>::pair(std::piecewise_construct_t,
std::tuple<Args1...>, std::tuple<Args2...>);
在這種特殊情況下,您甚至可以省略std::piecewise_construct
m.emplace(std::forward_as_tuple(1,2,3),
std::forward_as_tuple(4,5,6));
或(如 Nicol 在評論中指出的在 C++17 中)
m.emplace(std::tuple(1,2,3), std::tuple(4,5,6));
相當於
m.emplace(ThreeTuple(1,2,3), ThreeTuple(4,5,6));
並調用構造函數
template<typename T1, typename T2>
std::pair<T1,T2>::pair(const&T1, const&T2);
另請注意,AFAIK 您無法通過顯式使用std::initializer_list<int>
。 原因很簡單, pair<ThreeTuple,ThreeTuple>
(地圖的value_type
)沒有合適的構造函數。
但是為什么不能將初始化列表直接傳遞給
map::emplace()
因為初始化列表不是表達式,所以它們沒有類型。 emplace()
的簽名只是:
template< class... Args >
std::pair<iterator,bool> emplace( Args&&... args );
並且您無法從{1,2,3}
推斷出類型。 你不能在 C++11 中,你仍然不能在 C++1z 中。 此規則的唯一例外是如果模板參數的格式為std::initializer_list<T>
,其中T
是模板參數。
為了m.emplace({1,2,3},{4,5,6});
要工作,您需要一個簽名,例如:
std::pair<iterator,bool> emplace(key_type&&, mapped_type&&);
類似的東西可以在C++17
:
m.try_emplace({1,2,3},4,5,6);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.