我真的需要为 const 对象实现用户提供的构造函数吗?

2024-01-13

我有代码:

class A {
  public:
    A() = default;

  private:
    int i = 1;
};

int main() {
  const A a;
  return 0;
}

它在 g++ 上编译得很好(参见ideone http://ideone.com/PryGs5),但在 clang++ 上失败并出现错误:

const 类型“const A”对象的默认初始化需要用户提供的默认构造函数

我报告了这个问题LLVM 错误跟踪器 http://llvm.org/bugs/show_bug.cgi?id=18882#c1并得到它无效。

我认为试图说服 clang 开发人员是绝对没有意义的。另一方面,我不明白这种限制的原因。


如果 C++11 标准以某种方式暗示此代码无效,任何人都可以提出建议吗?或者我应该向 g++ 报告错误?或者也许语言规则有足够的自由度来以多种方式处理此代码?


N3797 §8.5/7 说:

如果程序调用 const 限定类型 T 的对象的默认初始化,则 T 应是具有用户提供的默认构造函数的类类型。

没有进一步的例子或解释。我同意这看起来很奇怪。此外,当需要类类型时,C++11 中的规则比 C++03 中的规则更严格用户声明的构造函数。 (您的构造函数是用户声明的。)

解决方法是要求使用值初始化{},还是用Dietmar的聪明出类拔萃inline定义。

如果您添加另一个没有初始化程序的成员,GCC 确实提供了一个诊断(而且是一个非常好的诊断,指的是较新的 C++11 要求)。

  private:
    int i = 1;
    int j;

 

unmem.cpp:11:11: error: uninitialized const ‘a’ [-fpermissive]
   const A a;
           ^
unmem.cpp:1:7: note: ‘const class A’ has no user-provided default constructor
 class A {
       ^
unmem.cpp:3:5: note: constructor is not user-provided because it is explicitly defaulted in the class body
     A() = default;
     ^
unmem.cpp:7:9: note: and the implicitly-defined constructor does not initialize ‘int A::j’
     int j;

The GCC 指的是DR 253 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#253, 为什么必须初始化空或完全初始化的 const 对象?这是标准中的一个未决问题,最后更新于 2011 年 8 月(C++11 后),并附有以下注释:

如果隐式默认构造函数初始化所有子对象,则不需要初始化程序。

因此,虽然 Clang 符合 C++11(并将按原样符合 C++14),但 GCC 正在实施标准化委员会的最新想法。

Filed a GCC bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60284。我预测你会需要-pedantic当(以及如果)错误被修复时获得诊断。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我真的需要为 const 对象实现用户提供的构造函数吗? 的相关文章

随机推荐