请考虑以下代码,使用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,6}); }
我原以为map :: emplace()的initializer_list参数已经足够了,并且会导致将元组键插入指定的元组值关联.显然,编译器不同意.
当然创建一个元组显式(即,ThreeTuple {1,3}而不仅仅是{1,3})并将其传递给map :: emplace()解决了问题,但为什么不能初始化列表直接传递给map :: emplace(),它会自动将它们转发给元组构造函数?
解决方法
but why can’t the initializer lists be passed directly to
map::emplace()
因为初始化列表不是表达式,因此它们没有类型. emplace()
的签名只是:
template< class... Args > std::pair<iterator,bool> emplace( Args&&... args );
而且你不能从{1,3}中推断出一种类型.你不能在C 11中,你仍然不能在C 1z.此规则的唯一例外是模板参数的格式为std :: initializer_list< T>其中T是模板参数.
为了m.emplace({1,6});工作,你需要一个签名,如:
std::pair<iterator,bool> emplace(key_type&&,mapped_type&&);