【问题标题】:Reordering member declaration重新排序成员声明
【发布时间】:2014-05-20 20:32:15
【问题描述】:

在 C++ 标准中有来自 3.3.7/1 的引用:

如果对类中的成员声明重新排序会产生一个替代的有效 (1) 和 (2) 下的程序,程序格式错误,没有诊断 必填。

这是什么意思?你能得到一个这样的重新排序声明的例子吗?

【问题讨论】:

  • 成员声明的顺序很重要的一个例子是构造。初始化值时,您可能会初始化一个依赖于另一个的值。如果类中的顺序错误,则可能初始化得太早(在其他成员初始化之前)。

标签: c++ class


【解决方案1】:

考虑这个程序:

double foo;
class Bar {
    std::vector<decltype(foo)> v;
    int foo;
};

重新排序 Bar::vBar::foo 像这样:

double foo;
class Bar {
    int foo;
    std::vector<decltype(foo)> v;
};

将产生一个在其他方面有效的替代程序,因此该程序违反了引用的规则。

(一个版本的)gcc 选择在第一种情况下发出错误,但使用第二种变体进行编译(“不需要诊断”)。

std::vector&lt;decltype(::foo)&gt; v;std::vector&lt;decltype(Bar::foo)&gt; v; 是有效的替代方案(只有在首先声明 Bar::foo 时才可能使用后者)。

【讨论】:

  • 我认为你的意思是两者的第一行都是double foo;
【解决方案2】:

这种情况的一个例子是您在对象构造中可能遇到的常见错误。 代码变体 1 和 2 说明了这一点。 代码变体 1:

class C
{
  C() : a1(0), a2(a1)
  {
  }

  int a1;
  int a2;
};

代码变体 2:

class C
{
  C() : a1(0), a2(a1)
  {
  }

  int a2;
  int a1;
};

请注意,在变体 2 中,a1 和 a2 成员声明顺序已更改。好的编译器会对代码变体 2 提供警告:“成员初始化与声明顺序不同”。 问题在于代码变体 2 中的程序行为未定义。一些编译器将生成代码,其中 a2 将以 0 初始化(例如,据我所知,Visual Studio 编译器),一些编译器将生成 a2 值未定义的代码,而在代码变体 1 中,任何编译器都将提供正确的代码。 所以这是你需要的例子。

【讨论】:

  • 我不确定这算不算一个备用有效程序。
猜你喜欢
  • 1970-01-01
  • 2019-03-16
  • 1970-01-01
  • 2013-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多