【问题标题】:C++11 "In class initialization" feature is not working for unionsC++11“类内初始化”功能不适用于联合
【发布时间】:2013-07-22 14:33:24
【问题描述】:

最小代码示例:

struct B { 
  union U {
    struct S {} s;
    int i = 100;
  }
  u;  
};

现在如果我们声明一个B obj;,那么obj.u.i 会被分配一个垃圾值而不是100。请参阅demo here。 (垃圾值因优化标志等而异)。

“类内初始化”功能是否应该与联合一起使用。

  • 如果是,那么正确的语法是什么?还是这是一个 g++ 错误?
  • 如果不是,那么int i = 100; 会做什么?

【问题讨论】:

  • clang 似乎对您的代码很满意。
  • @Praetorian,谢谢。但是,您还没有放置输出语句。所以这里是正确的clang output

标签: c++ c++11 unions in-class-initialization


【解决方案1】:

这看起来像一个 GCC 错误。标准说(9.5p2):

联合的最多一个非静态数据成员可以有一个brace-or-equal-initializer

否则,规则与普通课程相同。

编辑:此外,12.6.2p8:

在非委托构造函数中,如果给定的非静态数据成员或 基类不是由 mem-initializer-id 指定的(包括 没有的情况 mem-initializer-list 因为构造函数没有ctor-initializer)并且实体不是抽象类(10.4)的虚拟基类,那么

  • 如果实体是具有 brace-or-equal-initializer 的非静态数据成员,则实体按照 8.5 中的规定进行初始化;
  • 否则,如果实体是变体成员 (9.5),则不执行初始化;
  • 否则,实体默认初始化 (8.5)。

大概隐式定义的默认构造函数在这里计数。 i 成员符合第一个要点中的条件,因此它像普通类成员一样被初始化。 s 成员与第二个要点匹配,因此未初始化。

【讨论】:

  • 它不能在 VS 2010 和 2012 上编译,甚至在第一个版本上也不能编译,错误是:只能在类中初始化静态 const 整数数据成员。或者两个编译器都有错误或者还有更多...
  • @neagoegab 这些 VS 版本都不支持数据成员的类内初始化。 clang 正在编译代码,没有错误。
【解决方案2】:

我认为是这样的,因为联合可以重新组合多个元素。以下是解决语法的方法:

struct B { 
  union U {
    int i;
  }
  u {100};  
};

int main () {
  B obj;
  std::cout << "obj.u.i = " << obj.u.i << "\n";
}

【讨论】:

  • 请停止猜测。发布您知道并且可以支持的答案。
  • @Nawaz,我相信我支持我的回答。另一种方法是在标准中找到它,但你比我快:D,但我会更新答案。
  • 这个解决方案不适用于我的实际问题,只需在union U 中添加struct S {} s;,程序就会给出compiler error。我已经相应地更新了问题。
  • @iammilind 解决方法是为U: U() : i(100) {} 定义一个默认构造函数,而不是使用类内成员初始化。
猜你喜欢
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多