如何在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
相关产品推荐
相关产品推荐

