C++11 anonymous union with non-trivial members

后端 未结 2 1923
情话喂你
情话喂你 2020-12-01 02:52

I\'m updating a struct of mine and I was wanting to add a std::string member to it. The original struct looks like this:

struct Value {
  uint64_t lastUpdat         


        
2条回答
  •  没有蜡笔的小新
    2020-12-01 03:37

    There is no need for placement new here.

    Variant members won't be initialized by the compiler-generated constructor, but there should be no trouble picking one and initializing it using the normal ctor-initializer-list. Members declared inside anonymous unions are actually members of the containing class, and can be initialized in the containing class's constructor.

    This behavior is described in section 9.5. [class.union]:

    A union-like class is a union or a class that has an anonymous union as a direct member. A union-like class X has a set of variant members. If X is a union its variant members are the non-static data members; otherwise, its variant members are the non-static data members of all anonymous unions that are members of X.

    and in section 12.6.2 [class.base.init]:

    A ctor-initializer may initialize a variant member of the constructor’s class. If a ctor-initializer specifies more than one mem-initializer for the same member or for the same base class, the ctor-initializer is ill-formed.

    So the code can be simply:

    #include 
    
    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)
    {
    }
    

    Of course, placement new should still be used when vivifying a variant member other than the other initialized in the constructor.

提交回复
热议问题