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

如何在std::array中构造元素而非赋值?(针对不可赋值类)

问题描述

我有一个不可赋值的类MyClass,它的拷贝赋值与移动赋值运算符被删除了。实际场景中这个类包含std::variant成员,而variant的可选类型因含引用成员无法重绑定,所以类不可赋值。

代码示例:

class MyClass
{
public:
    MyClass() {}
    MyClass(int a) {}
    MyClass(MyClass &other) = default;
    MyClass(MyClass &&other) = default;
    MyClass &operator=(MyClass &) = delete;
    MyClass &operator=(MyClass &&) = delete;
};

我创建了该类的std::array:

std::array<MyClass, 5> my_array; // 默认初始化所有对象

尝试向数组中放入新对象时使用赋值操作:

my_array[1] = {69};

但触发错误:

error: use of deleted function ‘MyClass& MyClass::operator=(MyClass&&)’
   29 |     my_array[1] = {69};
      |                      ^

请问是否有办法强制构造数组元素而非进行赋值操作?

解决方案

可以通过销毁原有对象后在原内存位置构造新对象的方式实现,以下是两种常用方法:

方法1:使用std::destroy_at + std::construct_at(C++17及以上)

这是C++17引入的类型安全的内存操作函数,直接操作对象的内存地址:

// 销毁数组索引1处的原有对象
std::destroy_at(&my_array[1]);
// 在原内存位置构造新的MyClass对象,传入初始化参数69
std::construct_at(&my_array[1], 69);

方法2:使用placement new(C++11及以上)

这是更底层的手动内存操作方式,逻辑和上面一致:

// 显式调用析构函数销毁原有对象
my_array[1].~MyClass();
// 在已有内存地址上构造新对象
new (&my_array[1]) MyClass(69);

注意要点

  • 执行操作前确保原有对象的资源不再需要,因为销毁后无法恢复。
  • 你的类支持移动和拷贝构造,所以构造新对象时可以正常传递参数。

内容的提问来源于stack exchange,提问作者BlueMoon93

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:37:21