提问人:BlueMoon93 提问时间:7/29/2023 更新时间:7/29/2023 访问量:101
如何构造(而不是分配)std::array元素?
How can I construct (instead of assign) an std::array element?
问:
我有一个无法重新分配的班级。实际动机是它有一个成员变量,并且由于有一些引用成员变量(不能重新组合),可能的类型是不可重新分配的。这是我们所拥有的非常简单的版本:std::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<MyClass, 5> my_array; // default initializes all objects
最终,我想创建一个新对象并将其放入数组中。
my_array[1] = {69};
但是std::array试图分配,所以我得到一个错误。
error: use of deleted function ‘MyClass& MyClass::operator=(MyClass&&)’
29 | my_array[1] = {69};
| ^
有没有办法强制重建而不是重新分配元素?
答:
1赞
fabian
7/29/2023
#1
不,没有办法强制重建不是未定义的行为,至少在不破坏预先存在的元素并使用放置新的情况下。
既然你提到:你可以改变元素类型,即使在元素被构造之后,无论元素类型是否是可复制的/可移动的。只需使用 std::variant::emplace
。std::variant
std::variant
下面的示例实现赋值运算符,使代码类似于 work。MyClass
my_array[1] = {69};
struct IntHolder
{
int& m_value;
IntHolder(int& value)
: m_value(value)
{
}
};
using Variant = std::variant<std::monostate, IntHolder>;
class MyClass
{
Variant m_member;
public:
MyClass() {}
MyClass(int& a)
{
m_member.emplace<IntHolder>(a);
}
// we'll remove both move and copy semantics for MyClass
MyClass(MyClass&& other) = delete;
MyClass& operator=(MyClass&&) = delete;
MyClass& operator=(std::reference_wrapper<int> a)
{
m_member.emplace<IntHolder>(a);
return *this;
}
friend std::ostream& operator<<(std::ostream& s, MyClass const& value)
{
if (std::holds_alternative<IntHolder>(value.m_member))
{
s << "{ IntHolder { value = " << std::get<IntHolder>(value.m_member).m_value << " } }";
}
else
{
s << "{ std::monostate }";
}
return s;
}
};
void Print(std::array<MyClass, 2> const& a)
{
for (auto& e : a)
{
std::cout << e << '\n';
}
}
int main()
{
int x = 1;
int y = 2;
std::array<MyClass, 2> arr{ x, y };
std::cout << "after initialization\n";
Print(arr);
// "swap"
arr[0] = std::ref(y);
arr[1] = std::ref(x);
std::cout << "after modification\n";
Print(arr);
}
评论
std::array
std::array<MyClass, 5> my_array{1, 2, 3, 4, 5};