sky*_*ack 12 c++ language-lawyer noexcept c++11 inheriting-constructors
我不确定这是GCC编译器的错误还是预期的行为noexcept.
请考虑以下示例:
struct B {
B(int) noexcept { }
virtual void f() = 0;
};
struct D: public B {
using B::B;
D() noexcept(noexcept(D{42})): B{42} { }
void f() override { }
};
int main() {
B *b = new D{};
}
Run Code Online (Sandbox Code Playgroud)
如果noexcept删除它,它编译.
无论如何,正如在例子中,我从GCC v5.3.1得到了这个错误:
test.cpp:8:31: error: invalid use of incomplete type ‘struct D’
D() noexcept(noexcept(D{42})): B{42} { }
^
Run Code Online (Sandbox Code Playgroud)
据我所知,struct D不是一个不完整的类型,但继承构造函数涉及到语句,看起来编译器实际上考虑的是基本结构的完整性而B不是D.
这是预期的行为还是合法代码?
为清楚起见:
有关更多详细信息,请参阅此链接以获取GCC编译器的bugzilla.
目前,该错误仍未得到证实.我会尽快更新问题.
Geo*_*ard 12
您的代码是合法的,即使海湾合作委员会另有说法.这个看起来很滑稽的宣言违反了它:
D() noexcept(noexcept(D{42}));
Run Code Online (Sandbox Code Playgroud)
最外面的noexcept是一个noexcept说明符,D::D()当且仅当其constant-expression参数的计算结果为true时,表示noexcept.inner noexcept是一个noexcept运算符,它在编译时检查它的参数表达式(实际上没有被计算)是否会抛出异常.因为D::D(int)是noexcept(继承自B),所以这应该是真的.
cppreference.com明确指出允许在说明符中使用运算符(强调添加):
noexcept运算符执行编译时检查,如果声明表达式不抛出任何异常,则返回true.
它可以在函数模板的noexcept说明符中使用,以声明该函数将为某些类型而不是其他类型抛出异常.
现在,由于标准的§9.2.2(添加了大胆的重点),该类应该在noexcept说明符中被认为是完整的:
}在类说明符结束时,类被视为完全定义的对象类型(3.9)(或完整类型).在类成员规范中,该类在函数体,默认参数,using-declaration中被认为是完整的,为非静态数据引入了继承构造函数(12.9),异常规范 s和大括号或大小写器.成员(包括嵌套类中的这些东西).否则,它在其自己的类成员规范中被视为不完整.
§15.4.1将异常规范定义为以下语法:
异常规范:
动态异常规范
noexcept规格
所以GCC不应该拒绝你的代码.