继承构造函数时std :: is_nothrow_constructible

Art*_*zuk 6 c++ c++11

考虑以下两个例子:

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 {} 
};
Run Code Online (Sandbox Code Playgroud)

和用法:

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;
Run Code Online (Sandbox Code Playgroud)

输出是:

1
1
0
1
Run Code Online (Sandbox Code Playgroud)

使用的编译器:GCC 4.8.1.

所以,如果我显式写默认B构造函数,(X)生成1,另一方面如果默认C构造函数因继承而可用,则(Y)生成0.为什么?

这是否意味着在使用is_nothrow_constructible特征时不考虑继承的构造函数?

Hol*_*olt 7

这里的问题是模板化构造函数隐藏了继承的构造函数.从§12.9/ 4开始:

一个如此声明的构造函数[...].如果删除X中的相应构造函数(8.4.3)或者删除默认的默认构造函数(12.1),则删除它,[...].

以下编译没有问题:

struct C: A {
    using A::A;
};
static_assert(std::is_nothrow_constructible<C>{}, "");
Run Code Online (Sandbox Code Playgroud)