如何在std::vector<std::pair>中emplace时避免提前构造内部对象?
问题描述
现有如下两个结构体:
struct FIRST{ int a=0; int b=0; FIRST(int a, int b): a(a), b(b){} }; struct SECOND{ int c=0; int d=0; SECOND(int c, int d): c(c), d(d){} };
我们定义了一个存储上述结构体组成的pair的vector:
std::vector<std::pair<FIRST, SECOND>> abcd;
希望使用emplace_back添加元素,但不想提前构造FIRST和SECOND对象(即不想用abcd.emplace_back(FIRST(1,2),SECOND(3,4))这种写法),但直接传入abcd.emplace_back(1,2,3,4)无法生效。请问该如何实现?是否可行?
解决方案
完全可行,核心是利用std::pair的分段构造重载,以下是具体实现方式:
标准实现(C++11及以上)
使用std::piecewise_construct标签配合std::forward_as_tuple,可以直接传递两个结构体的构造参数,全程不会产生临时对象:
#include <tuple> // 必须包含此头文件 abcd.emplace_back(std::piecewise_construct, std::forward_as_tuple(1, 2), std::forward_as_tuple(3, 4));
原理说明
std::piecewise_construct是一个特殊的标签类,用于告知std::pair的构造函数采用分段构造模式;std::forward_as_tuple会将传入的参数打包为右值引用类型的tuple,pair会分别用这两个tuple中的参数,就地构造第一个元素(FIRST)和第二个元素(SECOND),避免了临时对象的创建。
为什么直接传1,2,3,4无效?
std::pair<FIRST, SECOND>没有匹配四个int参数的构造函数,emplace_back会将参数转发给pair的构造函数,但找不到对应的重载,因此编译失败。
内容的提问来源于stack exchange,提问作者MPEI_stud
相关产品推荐
相关产品推荐

