请考虑以下示例:
#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;
}
使用g ++编译,但不使用clang ++编译,尝试使用以下命令:clang++ -std=c++11 -O0 main.cpp && ./a.out
从clang编译错误:
main.cpp:19:13:错误:const类型'const A'对象的默认初始化需要用户提供的默认构造函数
我从This Stack Overflow Question了解到,非POD类获取默认构造函数。这甚至不是必需的,因为变量具有c ++ 11样式的默认初始化
为什么这不适合铿锵?
为什么A() = default;
也不起作用?
答案 0 :(得分:5)
这在CWG issue #253中讨论,讨论了对于空对象或其子对象已完全初始化的对象(在您的示例中就是这种情况)的用户提供的构造函数的需要。
引用部分链接问题
2011年8月会议记录:
如果隐式默认构造函数初始化所有子对象,则不需要初始化程序。
从技术上讲,这是一个活跃的问题,但考虑到这一点,它可能会像gcc选择实现它一样得到解决。
另一方面,在实施解决方案之前,Clang已经解决了chosen to wait问题。在Clang,我们等待问题实际得到解决,然后我们就此发表指示。
所以,就目前而言,铿锵是正确的。
答案 1 :(得分:2)
你自己引用了答案。在您链接的SO答案中,标准中引用了以下引用(第6.8.6节准确):
强调我的。这条线如果程序要求默认初始化a的对象 const限定类型T,T应为具有用户提供的类类型 默认构造函数。
A() = default;
显然不提供构造函数,它通过告诉编译器您不想提供构造函数来反过来,因此您的代码不会编译。但是,一旦通过取消注释提供构造函数
A(){};
它工作正常。因此,总而言之,clang显示的错误是按标准进行的,而gcc的行为可能是一个错误。