我正在更新我的一个结构,我想向其中添加一个 std::string 成员。原始结构如下所示:
struct Value {
uint64_t lastUpdated;
union {
uint64_t ui;
int64_t i;
float f;
bool b;
};
};
当然,仅向联合体添加一个 std::string 成员就会导致编译错误,因为通常需要添加对象的重要构造函数。
由于 std::string 定义了所有六个特殊成员函数,因此 U 将具有隐式删除的默认构造函数、复制构造函数、复制赋值运算符、移动构造函数、移动赋值运算符和析构函数。实际上,这意味着除非显式定义一些或全部特殊成员函数,否则您无法创建 U 的实例。
然后网站继续给出了以下示例代码:
union U
{
int a;
int b;
string s;
U();
~U();
};
但是,我在结构中使用匿名联合。我在 freenode 上询问了 ##C++,他们告诉我正确的方法是将构造函数放入结构中,并给了我以下示例代码:
#include <new>
struct Point {
Point() {}
Point(int x, int y): x_(x), y_(y) {}
int x_, y_;
};
struct Foo
{
Foo() { new(&p) Point(); }
union {
int z;
double w;
Point p;
};
};
int main(void)
{
}
但从那里我无法弄清楚如何定义 std::string 需要定义的其余特殊函数,而且,我并不完全清楚该示例中的 ctor 是如何工作的。
我可以找人向我解释一下吗?
这里不需要放置新的。
变体成员不会由编译器生成的构造函数初始化,但选择一个成员并使用正常的初始化应该没有问题构造函数初始化列表。在匿名联合内部声明的成员实际上是包含类的成员,并且可以在包含类的构造函数中初始化。
此行为在第 9.5 节中进行了描述。[class.union]
:
A 类似联盟的class 是联合体或具有匿名联合体作为直接成员的类。一个像工会一样的班级X
有一组变体成员. If X
是一个联合体,其变体成员是非静态数据成员;否则,其变体成员是属于以下成员的所有匿名联合的非静态数据成员X
.
以及第 12.6.2 节中[class.base.init]
:
A 构造函数初始化器可以初始化构造函数类的变体成员。如果一个构造函数初始化器指定多个内存初始化器对于同一成员或同一基类,构造函数初始化器格式不正确。
所以代码可以很简单:
#include <new>
struct Point {
Point() {}
Point(int x, int y): x_(x), y_(y) {}
int x_, y_;
};
struct Foo
{
Foo() : p() {} // usual everyday initialization in the ctor-initializer
union {
int z;
double w;
Point p;
};
};
int main(void)
{
}
当然,当激活一个变体成员而不是在构造函数中初始化的其他成员时,仍然应该使用放置 new 。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)