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

复制存储不可复制构造且不可复制赋值元素的std::vector

复制存储不可复制构造且不可复制赋值元素的std::vector

嘿,这个问题挺有意思的,咱们一步步拆解来看:

首先结论是你没法直接复制这个std::vector<A>,原因出在C++对构造函数匹配的优先级规则上,咱们慢慢说:

  • 当你尝试拷贝一个std::vector<A>时,vector的拷贝构造逻辑会遍历源容器里的每个元素,用const A&类型的参数去构造新容器里的对应元素。
  • 你的类A虽然写了一个泛型构造函数A(auto&&),看起来好像能接受任何类型的参数,但这里有个关键规则:用户显式声明的特殊成员函数(比如你删除的A(const A&)拷贝构造函数),优先级比模板构造函数更高。
  • 所以当编译器看到用const A&构造A的需求时,它会直接匹配你那个被delete的拷贝构造函数,而不是去实例化那个泛型模板构造函数。这就直接导致编译失败——毕竟你明确告诉编译器这个构造函数不能用。

咱们可以用代码验证一下,比如写这么一行:

std::vector<A> v1;
std::vector<A> v2 = v1; // 这行代码会编译报错

编译器会提示你尝试调用了被删除的函数A::A(const A&),完全不会用到那个泛型构造函数。

如果真的想实现类似“复制”vector的效果,你得调整A的构造函数约束,比如让泛型构造函数在参数是A类型时也能被选中,但这需要用概念排除掉拷贝构造的匹配场景,比如:

struct A {
    A() {}
    A(const A&) = delete;
    template<typename T>
    requires (!std::same_as<std::remove_cvref_t<T>, A>)
    A(T&&) {}
    A& operator=(const A&) = delete;
};

不过这样一来,这个泛型构造函数就不再接受A类型的参数了,你还是没法直接拷贝vector——因为这时候连构造A的途径都没了。本质上,如果你想让vector能被拷贝,元素类型必须满足可拷贝构造的要求,而你的A因为显式删除了拷贝构造函数,已经不符合这个要求了。

备注:内容来源于stack exchange,提问作者Fedor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:58:07