如何用emplace_back向tuple类型std::vector添加元素且避免临时对象?
用emplace_back构造vector中tuple内的Foo且避免临时对象的正确方法
你需要在std::vector<std::tuple<int, int, Foo>>中通过emplace_back直接构造Foo成员,避免创建临时Foo对象,但使用std::forward_as_tuple传递Foo构造参数的写法编译失败,常规的Foo(1, 2.0f)写法会产生临时对象,不符合预期。
正确实现方式
要实现就地构造,需要借助std::piecewise_construct,它能告诉tuple分别用不同的参数列表就地构造每个成员。示例代码如下:
#include <utility> #include <vector> #include <tuple> struct Foo { int a; float b; Foo(int a, float b) : a(a), b(b) {} }; int main() { std::vector<std::tuple<int, int, Foo>> vec; // 就地构造tuple及其内部的Foo对象,无临时对象产生 vec.emplace_back( std::piecewise_construct, std::forward_as_tuple(0, 1), // 构造tuple前两个int成员的参数 std::forward_as_tuple(1, 2.0f) // 构造Foo成员的参数 ); }
原写法失败原因
std::forward_as_tuple(1, 2.0f)返回的是一个包含引用的tuple类型,而你的vector元素是std::tuple<int, int, Foo>,编译器无法将这个引用tuple隐式转换为Foo对象,因此编译报错。
为什么这种写法能避免临时对象
std::piecewise_construct会引导tuple分别使用传入的参数列表,直接在vector分配的内存中构造每个成员(包括Foo),整个过程不会产生任何临时对象,完全符合emplace_back"就地构造"的设计目标。
内容的提问来源于stack exchange,提问作者Yakov Dan
相关产品推荐
相关产品推荐

