如何在Union中初始化非pod成员?

时间:2021-09-28 22:45:00

In c++11, Union supports non-POD member. I want to initialize a non-POD member in the constructor.

在c++11中,Union支持非pod成员。我想在构造函数中初始化一个非pod成员。

On wikipedia c++11 page, it uses a placement 'new' to initialize a non-POD member.

在wikipedia c++11页面上,它使用一个放置“新”来初始化一个非pod成员。

#include <new> // Required for placement 'new'.

struct Point {
    Point() {}
    Point(int x, int y): x_(x), y_(y) {}
    int x_, y_;
};

union U {
    int z;
    double w;
    Point p; // Illegal in C++03; legal in C++11.
    U() {new(&p) Point();} // Due to the Point member, a constructor definition is now required.
};

I am wondering is there any difference if I use ctor-initializer-list instead of placement 'new'?

我想知道,如果我使用ctor-initializer-list而不是放置“new”,会有什么不同吗?

U() : p() {}

2 个解决方案

#1


1  

No, no difference for you. Just use U() : p() {}.

不,没有区别。只要使用U(): p(){}。

[ Note: In general, one must use explicit destructor calls and placement new operators to change the active member of a union. — end note ]

注意:一般来说,必须使用显式析构函数调用并放置新的操作符来更改union的活动成员。——结束注意)

[ Example: Consider an object u of a union type U having non-static data members m of type M and n of type N. If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new operator as follows:

(例如:考虑一个对象u联盟类型有非静态数据成员m m和n型n .如果m型有一个非平凡的析构函数和n有一个简单的构造函数(例如,如果他们声明或继承虚函数),u的活跃成员可以安全地从m,n使用析构函数和放置新的操作符如下:

u.m.~M();
new (&u.n) N;

— end example ]

——最后的例子)

I.e. your first variant is correct.

也就是说,你的第一个变体是正确的。


The standard also says:

标准还说:

At most one non-static data member of a union may have a brace-or-equal-initializer.

在大多数的非静态数据成员中,一个联合可能有一个或一个或多个初始值设定项。

Personally, I would expect the following to be correct:

就我个人而言,我认为以下几点是正确的:

union U {
    int z;
    double w;
    Point p {1,2};
};

#include <iostream>
int main () {
    U u;
    std::cout << u.p.x_ << ":" << u.p.y_ << std::endl;
}

I would expect the output 1:2, but with g++ 4.8.1 I get garbage values. When I try

我希望输出是1:2,但是使用g++ 4.8.1我得到了垃圾值。当我尝试

union U {
    int z;
    double w;
    Point p = Point(1,2);
};

I get garbage values, too. I am not sure if this is a compiler bug.

我也得到了垃圾值。我不确定这是不是一个编译器错误。

edit: brace-or-equal-Initializer in unions

编辑:brace-or-equal-Initializer工会

#2


1  

You are free to initialize at most one member of a union in the ctor-initializer-list. A union is a class, so the rules for member initializers in [class.base.init] (C++11 §12.6.2) apply just as they do to classes with the class-key struct or class. One obvious exception is stated in 12.6.2/8: "An attempt to initialize more than one non-static data member of a union renders the program ill-formed."

您可以*地在ctor-initializer-list中初始化union的大多数成员。一个union是一个类,所以成员初始化器的规则在[class.base]中。init)(c++ 11§12.6.2)一样适用于类与类关键结构体或者类。在12.6.2/8中有一个明显的例外:“试图初始化一个union的多个非静态数据成员,使得程序不正常。”

#1


1  

No, no difference for you. Just use U() : p() {}.

不,没有区别。只要使用U(): p(){}。

[ Note: In general, one must use explicit destructor calls and placement new operators to change the active member of a union. — end note ]

注意:一般来说,必须使用显式析构函数调用并放置新的操作符来更改union的活动成员。——结束注意)

[ Example: Consider an object u of a union type U having non-static data members m of type M and n of type N. If M has a non-trivial destructor and N has a non-trivial constructor (for instance, if they declare or inherit virtual functions), the active member of u can be safely switched from m to n using the destructor and placement new operator as follows:

(例如:考虑一个对象u联盟类型有非静态数据成员m m和n型n .如果m型有一个非平凡的析构函数和n有一个简单的构造函数(例如,如果他们声明或继承虚函数),u的活跃成员可以安全地从m,n使用析构函数和放置新的操作符如下:

u.m.~M();
new (&u.n) N;

— end example ]

——最后的例子)

I.e. your first variant is correct.

也就是说,你的第一个变体是正确的。


The standard also says:

标准还说:

At most one non-static data member of a union may have a brace-or-equal-initializer.

在大多数的非静态数据成员中,一个联合可能有一个或一个或多个初始值设定项。

Personally, I would expect the following to be correct:

就我个人而言,我认为以下几点是正确的:

union U {
    int z;
    double w;
    Point p {1,2};
};

#include <iostream>
int main () {
    U u;
    std::cout << u.p.x_ << ":" << u.p.y_ << std::endl;
}

I would expect the output 1:2, but with g++ 4.8.1 I get garbage values. When I try

我希望输出是1:2,但是使用g++ 4.8.1我得到了垃圾值。当我尝试

union U {
    int z;
    double w;
    Point p = Point(1,2);
};

I get garbage values, too. I am not sure if this is a compiler bug.

我也得到了垃圾值。我不确定这是不是一个编译器错误。

edit: brace-or-equal-Initializer in unions

编辑:brace-or-equal-Initializer工会

#2


1  

You are free to initialize at most one member of a union in the ctor-initializer-list. A union is a class, so the rules for member initializers in [class.base.init] (C++11 §12.6.2) apply just as they do to classes with the class-key struct or class. One obvious exception is stated in 12.6.2/8: "An attempt to initialize more than one non-static data member of a union renders the program ill-formed."

您可以*地在ctor-initializer-list中初始化union的大多数成员。一个union是一个类,所以成员初始化器的规则在[class.base]中。init)(c++ 11§12.6.2)一样适用于类与类关键结构体或者类。在12.6.2/8中有一个明显的例外:“试图初始化一个union的多个非静态数据成员,使得程序不正常。”