Rozważmy następujące klasy:noexcept operator i enable_if_t: czy współpracują ze sobą?
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 {}
};
Zgodnie z oczekiwaniami, to kompiluje:
s.f<void>();
Ten jeden nie zamiast:
s.g<void>();
Co mnie zastanawia to, że następujący main
kompiluje z GCC (6.2) i nie kompiluje się z klangiem (3.9):
int main() {
static_assert(noexcept(&S::f<void>), "!");
static_assert(noexcept(&S::g<void>), "!");
}
Powiedziałbym, że drugie twierdzenie nie powiodło się z powodu nieważnej specjalizacji. Dwa kompilatory nie zgadzają się z tym.
Która z nich jest poprawna?
Domyślam się, że GCC zdecydowało się na skrót, gdy się zorientuje, że 'g' jest szablonem funkcji członka i że' noexcept' może być tylko "prawdziwe". –
@ T.C. Być może, ale w tym przypadku specjalizacja jest nieważna. Czy nie powinno to zawodzić w przypadku 'S :: g' (pozwól mi powiedzieć) _nie mogę istnieć_? –
skypjack
Nie powiedziałem, że GCC ma rację. –