Spezialisiert auf nicht typisierte Template-Parameter des falschen Typs

Folgendes berücksichtigen

template <unsigned >
struct uint_ { };

template <class >
struct X {
    static constexpr bool value = false;
};

template <int I> // NB: int, not unsigned
struct X<uint_<I>> {
    static constexpr bool value = true;
};

int main() {
    static_assert(X<uint_<0>>::value, "!");
}

clang kompiliert den Code, gcc nicht.

Im folgenden stark verwandten Beispiel jedoch:

template <unsigned >
struct uint_ { };

template <int I> // NB: int, not unsigned
void foo(uint_<I> ) { }

int main() {
    foo(uint_<0>{} );
}

Beide Compiler lehnen ab, ohne dass ein entsprechender Funktionsaufruf für @ vorliegfoo. Das Verhalten von gcc ist konsistent, das von clang nicht. Daher hat der eine oder andere Compiler einen Fehler für eines oder beide Beispiele. Welcher Compiler ist richtig?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage