Я сталкиваюсь с проблемой при использовании спецификатора noexcept
на производных классах, точнее, когда родитель является абстрактным классом (имеет конструкторы protected
).Использование noexcept в производных классах
Далее приведен пример того, как я объявляю свои классы.
- С конструктором
public
в базовом классе: все в порядке. - Тот же код с
protected
и производным классом не более «nothrow movable».
Пропустить что-нибудь? Является std::is_nothrow_move_constructible
правильными чертами для использования в объявлениях производного класса или я должен использовать что-то еще?
Спасибо за ваши ответы.
#include <cstdlib>
#include <iostream>
class BaseOk
{
public:
BaseOk (BaseOk&& other) noexcept {}
};
class BaseNok
{
protected:
BaseNok (BaseNok&& other) noexcept {}
};
class ChildOk : public BaseOk
{
public:
ChildOk (ChildOk&& other) noexcept (std::is_nothrow_move_constructible <BaseOk>::value)
: BaseOk (std::move (other)) {}
};
class ChildNok : public BaseNok
{
public:
ChildNok (ChildNok&& other) noexcept (std::is_nothrow_move_constructible <BaseNok>::value)
: BaseNok (std::move (other)) {}
};
int main()
{
std::cout << std::boolalpha;
std::cout << "Is BaseOk move constructible? " << std::is_move_constructible <BaseOk>::value << '\n';
std::cout << "Is ChildOk move constructible? " << std::is_move_constructible <ChildOk>::value << '\n';
std::cout << '\n';
std::cout << "Is BaseOk nothrow move constructible? " << std::is_nothrow_move_constructible <BaseOk>::value << '\n';
std::cout << "Is ChildOk nothrow move constructible? " << std::is_nothrow_move_constructible <ChildOk>::value << '\n';
std::cout << '\n';
std::cout << "Is BaseNok move constructible? " << std::is_move_constructible <BaseNok>::value << '\n';
std::cout << "Is ChildNok move constructible? " << std::is_move_constructible <ChildNok>::value << '\n';
std::cout << '\n';
std::cout << "Is BaseNok nothrow move constructible? " << std::is_nothrow_move_constructible <BaseNok>::value << '\n';
std::cout << "Is ChildNok nothrow move constructible? " << std::is_nothrow_move_constructible <ChildNok>::value << '\n';
std::cout << std::endl;
return EXIT_SUCCESS;
}
Выход:
Is BaseOk move constructible? true
Is ChildOk move constructible? true
Is BaseOk nothrow move constructible? true
Is ChildOk nothrow move constructible? true
Is BaseNok move constructible? false
Is ChildNok move constructible? true
Is BaseNok nothrow move constructible? false
Is ChildNok nothrow move constructible? false
___ EDIT ____________________________________________________________
После поиска вокруг некоторое время, и в отношении к andswer из Олег Богданов, он, к сожалению, кажется, не представляется возможным объединить protected
с использованием noexcept (is_nothrow_...)
.
Я писал абстрактные классы и объявлял конструкторы protected
только для целей документирования. Теперь конструкторы вернулись к public
, но я столкнулся с другой проблемой:
как абстрактный класс не может быть инстанциирован, std::is_nothrow_move_constructible<BaseClass>
возвращает false
и все производные классы не могут быть помечены как не выбрасывающие исключений, даже если они не являются.
смотрите пример ниже:
#include <cstdlib>
#include <iostream>
class Foo
{
public:
Foo (Foo&& other) noexcept {}
virtual ~Foo() = 0; // Removing '= 0' makes both outputs print 'true'.
};
Foo::~Foo() {}
class Bar : public Foo
{
public:
Bar (Bar&& other) noexcept (std::is_nothrow_move_constructible <Foo>::value)
: Foo (std::move (other)) {}
};
int main()
{
std::cout << std::boolalpha;
std::cout << "Foo: " << std::is_nothrow_move_constructible <Foo>::value << '\n';
std::cout << "Bar: " << std::is_nothrow_move_constructible <Bar>::value << '\n';
return EXIT_SUCCESS;
}
Выход:
Foo: false
Bar: false
Спасибо за ваш ответ. Да, я понял это. Я предложил минималистичную часть кода, но я попробовал со всеми определенными конструкторами (в 'protected'), и результат точно такой же.Я реализую абстрактный класс, и я попытался создать свой конструктор «protected» для целей документации (теперь я не обязателен). К сожалению, кажется, что невозможно использовать их 'protected' при использовании' noexcept' и 'std :: is _...'. –
Я переместил все мои конструкторы в 'public', но столкнулся с другой проблемой. Я отредактировал мой оригинальный пост ... –
Отредактировал свой ответ с дополнительными –