Ваш первый тест, не работает: этот проход
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 нет исключений теперь в типе