Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::is_nothrow_constructible when constructor is inherited

Tags:

c++

c++11

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?

like image 840
Artur Pyszczuk Avatar asked Dec 20 '16 09:12

Artur Pyszczuk


1 Answers

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>{}, "");
like image 191
Holt Avatar answered Oct 21 '22 06:10

Holt