Consider following two examples:
struct A {
A () noexcept = default;
};
struct B : A {
B () noexcept = default;
template <typename T>
B (T) noexcept {}
};
struct C : A {
using A::A;
template <typename T>
C (T) noexcept {}
};
and usage:
std::cout << std::is_nothrow_constructible<B>::value << std::endl; // (X)
std::cout << std::is_nothrow_constructible<B, int>::value << std::endl;
std::cout << std::is_nothrow_constructible<C>::value << std::endl; // (Y)
std::cout << std::is_nothrow_constructible<C, int>::value << std::endl;
Output is:
1
1
0
1
Compiler used: GCC 4.8.1.
So, If I write explicitly default B
constructor, (X)
produces 1, on the other hand if default C
constructor is available because of the inheritance, (Y)
produces 0. Why is that?
Does it mean that inherited constructors are not taken into account when is_nothrow_constructible
trait is used?
The problem here is that the templated constructor hides the inherited constructor. From §12.9/4:
A constructor so declared [...]. It is deleted if the corresponding constructor in X is deleted (8.4.3) or if a defaulted default constructor (12.1) would be deleted, [...].
The following compiles without problem:
struct C: A {
using A::A;
};
static_assert(std::is_nothrow_constructible<C>{}, "");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With