继承构造函数时std :: is_nothrow_constructible

时间:2016-12-20 09:38:05

标签: 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 {} 
};

和用法:

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;

输出是:

1
1
0
1

使用的编译器:GCC 4.8.1。

所以,如果我明确地写了默认B构造函数,(X)生成1,另一方面如果由于继承而导致默认C构造函数可用,(Y)会产生这是为什么?

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

1 个答案:

答案 0 :(得分:7)

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

  

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

以下编译没有问题:

struct C: A {
    using A::A;
};
static_assert(std::is_nothrow_constructible<C>{}, "");