Защищенный конструктор noexcept не выглядит как исключение из производного класса.Зачем? - PullRequest
0 голосов
/ 02 октября 2018

Вот источник:

#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.Но если бы я обнародовал конструкторы класса А. это работает.Почему?

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

1 Ответ

0 голосов
/ 02 октября 2018

std::is_nothrow_constructible и std::is_nothrow_move_constructible проверяют правильность формирования выражения

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

.Поскольку он выполняет эту проверку вне контекста класса, рассматривается доступ к члену.Поскольку ваши конструкторы защищены, выражение недопустимо, и признаки возвращают false.

...