[英]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.