最近Why does a const object requires a user-provided default constructor?被标记为Why does C++ require a user-provided default constructor to default-construct a const object?的副本。我正在使用coliru和rextexter来测试各种版本的gcc(g ++ - 4.7,g ++ - 4.8,g ++ - 4.9)和clang(3.4和3.5)来查看这种行为是否存在是在较新版本的编译器中引入的。这里我们分别从两个问题中提取了两个测试用例:
class A {
public:
void f() {}
};
int main()
{
A a; // OK
const A b; // ERROR
a.f();
return 0;
}
和
struct B{
B():x(42){}
int doSomeStuff() const{return x;}
int x;
};
struct A{
A(){}//other than "because the standard says so", why is this line required?
B b;//not required for this example, just to illustrate
//how this situation isn't totally useless
};
int main(){
const A a;
}
clang出错:
error: default initialization of an object of const type 'const A' requires a user-provided default constructor
A const a;
^
预计但不是gcc,也不是MSVC。我想也许我可能会发疯,因为标准引用清楚地说:
§8.5
6默认初始化T类型的对象意味着:
- 如果T是(可能是cv限定的)类类型(第9节),则为默认构造函数 调用T(如果T没有,则初始化是错误的 可访问的默认构造函数);
[...]
如果程序要求 const限定类型T,T的对象的默认初始化 应该是具有用户提供的默认构造函数的类类型。
11如果没有为对象指定初始值设定项,则对象为 默认初始化; [...]
第二个问题中出现的非POD语言似乎在n3337中缺失,所以也许我错过了一些可能已经改变的东西。这是一个错误,重复还是我错过了什么?
答案 0 :(得分:6)
规范目前需要用户提供的默认构造函数,但看起来GCC正在实现基于DR 253的更改,该更改表示如果所有子对象都将在没有用户提供的默认构造函数的情况下进行初始化,那么用户提供默认构造函数不是必需的。
此更改仅为草稿状态,尚未被接受且不属于标准。所以我认为这是GCC开发人员想要的行为,但我不确定这是否是符合标准的扩展。
这是对第一个导致GCC产生错误的示例的更改:
class A {
public:
void f() {}
int i;
};
int main()
{
A a; // OK
const A b; // ERROR
a.f();
return 0;
}
请注意,gcc使用-fpermissive标志将错误降级为警告。