skypjack
skypjack

Reputation: 50550

noexcept operator and enable_if_t: do they work together?

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?

Upvotes: 5

Views: 206

Answers (1)

Columbo
Columbo

Reputation: 60999

[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.

Upvotes: 3

Related Questions