noexcept, inheriting constructors and the invalid use of an incomplete type that is actually complete

老子叫甜甜 提交于 2019-12-05 00:29:33

Your code is legal, even though GCC claims otherwise. It takes offense at this funny-looking declaration:

D() noexcept(noexcept(D{42}));

The outermost noexcept is a noexcept specifier, stating that D::D() is noexcept if and only if its constant-expression argument evaluates to true. The inner noexcept is a noexcept operator that checks at compile time whether its argument expression, which is not actually evaluated, throws no exceptions. Because D::D(int) is noexcept (inherited from B), this should be true.

cppreference.com explicitly notes that using the operator inside the specifier is allowed (emphasis added):

The noexcept operator performs a compile-time check that returns true if an expression is declared to not throw any exceptions.

It can be used within a function template's noexcept specifier to declare that the function will throw exceptions for some types but not others.

Now, the class should be considered complete within the noexcept specifier due to §9.2.2 of the Standard (bold emphasis added):

A class is considered a completely-defined object type (3.9) (or complete type) at the closing } of the class-specifier. Within the class member-specification, the class is regarded as complete within function bodies, default arguments, using-declarations introducing inheriting constructors (12.9), exception-specifications, and brace-or-equal-initializers for non-static data members (including such things in nested classes). Otherwise it is regarded as incomplete within its own class member-specification.

§15.4.1 defines an exception-specification as the following grammar:

exception-specification:

  • dynamic-exception-specification

  • noexcept-specification

So GCC should not reject your code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!