You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:03:26