Can anyone explain me why using constructor marked as default
will have the error but the other one doesn't have. My understanding is they are very much similar.
Thanks.
class B {
public:
B() {
throw int(42);
}
};
class A {
public:
A() noexcept = default; // error: use of deleted function ‘A::A()’
// note: ‘A::A() noexcept’ is implicitly deleted because
// its exception-specification does not match the implicit exception-specification ‘’
//A() noexcept : m_b{}{}
B m_b;
};
CodePudding user response:
Implicit default constructor exception specification differs from your declaration of explicit default constructor. Here's the relevant (although outdated) part of the standard:
If a function that is explicitly defaulted is declared with an exception-specification that is not compatible (15.4) with the exception specification on the implicit declaration, then
- if the function is explicitly defaulted on its first declaration, it is defined as deleted;
- otherwise, the program is ill-formed.
In 2019 the proposal was made to change this behaviour. As I understand in c 20 your code will run just fine.
CodePudding user response:
Originally, the declaration of the constructor was already ill-formed, the idea being that the defaulted function ought to behave identically to the implicit declaration. Your explicit implementation has no such restriction: noexcept
functions are allowed to call potentially throwing functions, and the behavior is even well-defined if they throw.
In C 14 it was relaxed to be merely deleted in that case. Later it was realized that even that was too restrictive (and difficult to implement correctly), so it was relaxed again: now the exception specification can be anything (but there’s still an automatic one for defaulted functions).
Both of these changes were retroactive, so you’ll see a dependence on compiler version more than language version.
Note that none of this depends on the actual throw
in B::B
: that constructor is potentially throwing regardless.