使用默认初始化的 Clang 编译错误

Clang Compile error with default initialization

考虑以下示例:

#include <iostream>
#include <type_traits>

struct A
{
  //A() = default; // does neither compile with, nor without this line
  //A(){};         // does compile with this line
  int someVal{ 123 };


  void foobar( int )
  {
  };
};


int main()
{
    const A a;
    std::cout << "isPOD = " << std::is_pod<A>::value << std::endl;
    std::cout << "a.someVal = " <<a.someVal << std::endl;
}

See Live example

这可以用 g++ 编译但不能用 clang++ 编译,尝试使用以下命令:clang++ -std=c++11 -O0 main.cpp && ./a.out

clang 编译错误:

main.cpp:19:13: error: default initialization of an object of const type 'const A' requires a user-provided default constructor

我从 This Stack Overflow Question 那里了解到,非 POD 类 获得默认构造函数。这在这里甚至没有必要,因为变量具有 c++11 样式的默认初始化

为什么这不适用于 clang? 为什么 A() = default; 也不起作用?

你自己引用了答案。在您链接的 SO 答案中,引用了标准中的以下内容(准确地说是第 6.8.6 节):

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.

强调我的。行

A() = default;

显然不提供构造函数,它通过告诉编译器您不想提供构造函数来做相反的事情,因此您的代码无法编译。但是,一旦您通过取消注释

来提供构造函数
 A(){}; 

它工作正常。因此,总而言之,clang 显示的错误是符合标准的,而 gcc 的行为可能是一个错误。

这在 CWG issue #253 中得到解决,其中讨论了需要用户为空对象或子对象已完全初始化的对象提供构造函数(在您的示例中就是这种情况)。

引用部分链接问题

Notes from the August, 2011 meeting:

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

从技术上讲,这是一个活跃的问题,但考虑到这一点,它似乎很可能会按照 gcc 选择实现它的方式得到解决。

另一方面,Clang 会 chosen to wait 直到问题得到解决才能实施解决方案。

In Clang, we're waiting for the issue to actually be resolved before we take a direction on it.

因此,就目前而言,clang 是正确的。