2016-10-19 19 views
5

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?

+1

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". –

+0

@ 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

+2

Nie powiedziałem, że GCC ma rację. –

Odpowiedz

3

[except.spec]/13:

Zestaw potencjalnych wyjątkami wyrażenia e jest pusty, gdy e jest rdzeń wyrażenie stałe (5,20).

Oznacza to, że GCC nawet nie rozwiąże Template-id, ponieważ wie, z get-go, że wynik jest true (od g<void> nie jest statycznym członkiem dane specjalizacja szablonu, którego typ jest przeciążony operator&). Będąc sprytnym, zachowanie jest niezgodne, ponieważ każde wystąpienie szablonu powoduje zastąpienie argumentów w deklaracji szablonu funkcji.

+0

Ale to tylko błąd, jeśli tworzymy "g", i nie tworzymy instancji 'g', chyba że potrzebujemy definicji, a to nie pociąga za sobą przeciążenia, prawda? – Barry

+0

@Barry "Natychmiastowe" dotyczy definicji szablonu funkcji. Z tego powodu szablon funkcji nie jest tworzony, dopóki jego definicja nie jest wymagana. Podpis jest tworzony w wielu innych scenariuszach. W przeciwnym razie coś takiego jak 'decltype (g ())' nie patrzy na typ zwrotu 'g', co byłoby naprawdę dziwne. – Columbo

+0

Ale ten przypadek wymagałby wykonania rozdzielczości przeciążenia, która wyzwala tworzenie instancji. – Barry

Powiązane problemy