-1

Here is the source:

#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;
}

Compilation fails with err1, err2, err3 and err4. But if I made public the constructors of class A it works. Why?

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

Mate059
  • 103
  • 5

1 Answers1

2

std::is_nothrow_constructible and std::is_nothrow_move_constructible check if the expression

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

is well formed. Since it does this check outside the context of the class, member access is considered. Since your constructors are protected the expression is not legal and the traits return false.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402