noexcept operator and enable_if_t: do they work together?

c++, clang, gcc, language-lawyer, noexcept

Solution

[except.spec]/13:

The set of potential exceptions of an expression `e` is empty if `e` is a core constant expression (5.20).

That is, GCC does not even resolve the template-id, because it knows from the get-go that the result is `true` (since `g<void>` is not a static data member template specialization whose type has an overloaded `operator&`). While being clever, the behavior is non-conforming, because any occurrence of a template-id entails the substitution of the arguments into the declaration of the function template.

Problem

Consider the following class: ``` struct S { template<typename T> std::enable_if_t<std::is_void<T>::value> f() noexcept {} template<typename T> std::enable_if_t<not std::is_void<T>::value> g() noexcept {} }; ``` As expected, this compiles: ``` s.f<void>(); ``` This one does not instead: ``` s.g<void>(); ``` What puzzles me is that the following `main` compiles with GCC (6.2) and doesn't compile with clang (3.9): ``` int main() { static_assert(noexcept(&S::f<void>), "!"); static_assert(noexcept(&S::g<void>), "!"); } ``` I would have said the second assert failed because of the invalid specialization. The two compilers disagree on that. Which one is correct?

Original source