本文介绍了C ++ 11与非平凡成员的匿名联合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在更新我的结构,我想添加一个std :: string成员。原始结构如下所示:

  struct Value {
uint64_t lastUpdated;

union {
uint64_t ui;
int64_t i;
float f;
bool b;
};
};

只要向union添加std :: string成员,当然会导致编译错误,因为通常需要添加对象的非平凡构造函数。

然后网站继续给出以下示例代码:

  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是如何工作的。


解决方案

我可以让别人更清楚地解释这个问题吗?



变量成员不会被编译器生成的构造函数初始化,但应该没有麻烦选择一个并使用正常 ctor-initializer-list 。在匿名联合体中声明的成员实际上是包含类的成员,可以在包含类的构造函数中初始化。



这一行为在第9.5节中描述。 [class.union]

和第12.6.2节 [class.base.init]

所以代码可以简单:

  #include< new> 

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

struct Foo
{
Foo():p(){} //在ctor初始化器中通常的日常初始化
union {
int z ;
double w;
Point p;
};
};

int main(void)
{
}

当然,当生成一个变量成员而不是在构造函数中初始化的其他成员时,仍应使用placement new。


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 lastUpdated;

  union {
    uint64_t ui;
    int64_t i;
    float f;
    bool b;
  };
};

Just adding a std::string member to the union, of course, causes a compile error, because one would normally need to add the non-trivial constructors of the object. In the case of std::string (text from informit.com)

Then the website goes on to give the following sample code:

union U
{
int a;
int b;
string s;
U();
~U();
};

However, I'm using an anonymous union within a struct. I asked ##C++ on freenode and they told me the correct way to do that was to put the constructor in the struct instead and gave me this example code:

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

But from there I can't figure how to make the rest of the special functions that std::string needs defined, and moreover, I'm not entirely clear on how the ctor in that example is working.

Can I get someone to explain this to me a bit clearer?

解决方案

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]:

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

So the code can be simply:

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

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

这篇关于C ++ 11与非平凡成员的匿名联合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 15:32
查看更多