C++ vector用piecewise_construct调用emplace_back时tuple失败pair成功原因求解
根本原因
std::pair作为固定双元素的复合类型,C++11起专门提供了接收std::piecewise_construct_t标签的重载构造函数:会将后续传入的两个tuple分别展开,作为pair第一个、第二个成员的构造参数,这是你示例中t2、t3能正常编译的核心原因。std::tuple是支持任意长度元素的可变复合类型,没有设计对应std::piecewise_construct_t标签的构造函数。你向tuple的构造函数传入std::piecewise_construct时,编译器会尝试将这个标签作为tuple第一个元素(也就是你示例里的int*)的构造参数,类型完全不匹配,自然会触发模板推导替换失败。
解决方法
方法1:直接构造元素传入(兼容所有C++版本)
最直观的写法,直接构造每个tuple元素后传入emplace_back:
vector<std::tuple<int*, TestObj> > t4; t4.emplace_back(nullptr, TestObj(a1, a2));
该写法会产生TestObj的临时对象和一次移动构造,对性能要求不高的场景可以直接使用。
方法2:完全原位构造(C++20及以上)
如果要避免临时对象开销、实现完全原位构造,可以用tuple支持的std::in_place_index<I>标签,指定给第I个元素传递多组构造参数:
vector<std::tuple<int*, TestObj> > t4; t4.emplace_back( std::in_place_index<0>, nullptr, std::in_place_index<1>, a1, a2 );
这种写法没有任何临时对象产生,和pair的piecewise_construct写法效率完全一致。
内容的提问来源于stack exchange,提问作者Mint
相关产品推荐
相关产品推荐

