受保护的noexcept构造函数似乎与派生类无关。为什么?

时间:2018-10-02 19:48:56

标签: c++ noexcept

以下是来源:

#include <type_traits>
#include <utility>

class A {
protected: 
//public: // if public, it's fine. (?)
    A()noexcept{}
    A(A&&) noexcept{}
};

class B : public A {
    static_assert(std::is_nothrow_constructible<A>::value,"err1"); // ! err1
    static_assert(std::is_nothrow_move_constructible<A>::value,"err2"); // ! err2

public:
    B()noexcept(std::is_nothrow_constructible<A>::value):A(){}
    B(B&& o)noexcept(std::is_nothrow_move_constructible<A>::value):A(std::move(o)){}
};

int main(){
    static_assert(std::is_nothrow_constructible<B>::value,"err3"); // ! err3
    static_assert(std::is_nothrow_move_constructible<B>::value,"err4"); // ! err4
    return 0;
}

编译失败,出现err1,err2,err3和err4。 但是,如果我公开了A类的构造函数,它将起作用。 为什么?

(Clang 6.0,7.0; gcc 8.x; ...)

1 个答案:

答案 0 :(得分:2)

std::is_nothrow_constructiblestd::is_nothrow_move_constructible检查表达式是否

T obj(std::declval<Args>()...);

格式正确。由于它在类的上下文之外执行此检查,因此考虑了成员访问。由于您的构造函数受到保护,因此表达式不合法并且特征返回false。