如何在tuple的vector中构造不可拷贝的对象?
解决不可拷贝类移入tuple的vector的问题
你这段代码报错的核心原因是:调用emplace_back构造std::tuple<int, int, A>时,传入的临时A(4,2)对象需要被拷贝到tuple中,但A的拷贝构造函数已被显式删除。同时,由于你声明了拷贝构造函数(即便标记为delete),编译器不会自动生成默认的移动构造函数,所以也无法通过移动操作绕过拷贝限制。
无需修改类A的实现,有两种巧妙的解决思路:
方法一:用std::piecewise_construct原位构造A
通过std::piecewise_construct配合std::forward_as_tuple,让tuple直接在自身内存空间里构造A对象,完全避免拷贝或移动操作:
#include <iostream> #include <vector> #include <tuple> class A { public: int val1; int val2; A(int v1, int v2): val1(v1), val2(v2) {} // make non-copyable A(const A &other) = delete; A &operator=(const A &other) = delete; }; int main() { std::vector<std::tuple<int, int, A>> my_as; my_as.emplace_back( std::piecewise_construct, std::forward_as_tuple(4, 3), // 传递tuple前两个int的构造参数 std::forward_as_tuple(4, 2) // 传递A的构造参数 ); // 验证构造结果 auto& [num1, num2, a_obj] = my_as[0]; std::cout << num1 << " " << num2 << " " << a_obj.val1 << " " << a_obj.val2 << std::endl; return 0; }
方法二:C++17+ 用std::in_place_type原位构造
如果你的编译器支持C++17及以上标准,可以用更简洁的std::in_place_type语法,直接指定在tuple中原位构造A:
int main() { std::vector<std::tuple<int, int, A>> my_as; my_as.emplace_back(4, 3, std::in_place_type<A>, 4, 2); // 验证构造结果 auto& [num1, num2, a_obj] = my_as[0]; std::cout << num1 << " " << num2 << " " << a_obj.val1 << " " << a_obj.val2 << std::endl; return 0; }
两种方法的核心逻辑都是避免对A对象进行拷贝/移动,直接在tuple的目标内存位置构造A,完全符合你不修改类A实现的要求。
内容的提问来源于stack exchange,提问作者Alexander Richter
相关产品推荐
相关产品推荐

