C ++ 11 - Как исправить оператор noexcept, который не может обнаружить объявление функции со спецификатором noexcept - PullRequest
0 голосов
/ 04 мая 2019

Я создаю новую библиотеку для личных исследовательских целей и пытаюсь полностью понять инструменты стандартной библиотеки c ++ и основные функции. Теперь у меня проблемы с пониманием оператора noexcept.

Я написал несколько тестовых примеров с использованием оператора noexcept, и я озадачен результатом следующего утверждения:

...
void no_throw() noexcept;

static_assert(noexcept(no_throw), "This should be true");
static_assert(noexcept((std::declval<decltype(no_throw)>())()), "this also should be true");
...

Я ожидал, что этот код скомпилируется, но второе утверждение пройдет только при использовании флага компиляции c ++ 17; я выполнил тест с gcc8.1 и clang5.0. Я не тестировал с другими компиляторами.

Сбой с флагом c ++ 11 или c ++ 14. Может ли кто-нибудь объяснить мне, почему?

Спасибо

1 Ответ

1 голос
/ 04 мая 2019

Ваш первый тест, не работает: этот проход

void no_throw() noexcept(true) {};
void do_throw() noexcept(false) {};

static_assert(noexcept(no_throw), "");
static_assert(noexcept(do_throw), "");

Должен быть:

void no_throw() noexcept(true) {};
void do_throw() noexcept(false) {};

static_assert(noexcept(no_throw()), "");
static_assert(!noexcept(do_throw()), "");

Тогда почему только в 17:

До 17: спецификация noexcept не является частью источника типа функции: https://en.cppreference.com/w/cpp/language/noexcept_spec

Итак, если вы запустите этот код в 11:

template<class T>
   struct TD;

TD<decltype(no_throw)> e;
TD<decltype(std::declval<decltype(no_throw)>())> e2;

Вы получите:

prog.cc:14:24: error: aggregate 'TD<void()> e' has incomplete type and cannot be defined
 TD<decltype(no_throw)> e;
                        ^
prog.cc:15:50: error: aggregate 'TD<void (&)()> e2' has incomplete type and cannot be defined
 TD<decltype(std::declval<decltype(no_throw)>())> e2;

И в 17:

prog.cc:14:24: error: aggregate 'TD<void() noexcept> e' has incomplete type and cannot be defined
 TD<decltype(no_throw)> e;
                        ^
prog.cc:15:50: error: aggregate 'TD<void (&)() noexcept> e2' has incomplete type and cannot be defined
 TD<decltype(std::declval<decltype(no_throw)>())> e2;

Видите, в 17 нет исключений теперь в типе

...