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

标签 c++ c++11 constructor constants language-lawyer

我有代码:

class A {
  public:
    A() = default;

  private:
    int i = 1;
};

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

它在g++上编译正常(请参见ideone),但在clang++上失败,并显示以下错误:

default initialization of an object of const type 'const A' requires a user-provided default constructor



我在LLVM bug-tracker上报告了此问题,并使其无效。

我认为试图说服c族开发者是毫无意义的。另一方面,我看不出这种限制的原因。

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

最佳答案

N3797§8.5/ 7说:

If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.



没有进一步的示例或解释。我同意这看起来很奇怪。此外,当类类型需要用户声明的构造函数时,在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;

GCC source引用DR 253,为什么必须初始化空或完全初始化的const对象?这是标准中的一个未解决问题,最近一次更新于2011年8月(C++ 11之后),带有以下注释:

If the implicit default constructor initializes all subobjects, no initializer should be required.



因此,尽管Clang符合C++ 11(并将原样符合C++ 14),但GCC正在实现标准化委员会的最新思路。

提交了GCC bug。我预计您将需要-pedantic才能在(以及是否)修正了错误的情况下进行诊断。

关于c++ - 我真的需要为const对象实现用户提供的构造函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59473350/

相关文章:

c++ - 十六进制字符到 std::string 的 constexpr 转换

c++ - Placement-new 是否引入了序列点?

c++ - 多层次的友元

c++ - 忽略函数默认参数

c++ - C++11 中字符串文字的 Unicode 编码

c++11 - 在这种情况下,C++ 右值什么时候会被破坏?

c++ - 如何指定为成员字段对象调用哪个构造函数?

c# - C# 中的静态构造函数

c++ - 使用 push_back 将对象添加到 vector 工作正常,但是使用访问器语法 [ ] 添加对象,不起作用

c++ - 为什么 MSVC 大发脾气编译宏,而 G++ 是关于禅宗的?