Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 797
skypjack Avatar asked Oct 17 '22 23:10

skypjack


1 Answers

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

like image 104
Columbo Avatar answered Nov 03 '22 01:11

Columbo