Biorąc pod uwagę następujący szablon klasy:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
definiujemy Innerosobno dla każdej specjalizacji Outer:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
a następnie raz zdefiniuj funkcję członka fdla wszystkich specjalizacji Outer:
auto Outer<T>::f(Inner) -> void
{
}
ale Clang (9.0.0) narzeka:
error: variable has incomplete type 'Outer::Inner'
auto Outer<T>::f(Inner) -> void
^
Możemy uniknąć błędu kompilatora, podając również definicję Innerwszystkich innych specjalizacji Outer:
template<typename T>
struct Outer<T>::Inner {};
lub definiując fosobno dla każdej specjalizacji:
template<>
auto Outer<int>::f(Inner) -> void
{
}
template<>
auto Outer<double>::f(Inner) -> void
{
}
Zarówno GCC, jak i MSVC akceptują kod początkowy, co nasuwa pytanie; czy jest to błąd Clanga, czy jest to jedyna zgodna implementacja spośród wszystkich trzech?
Innerdla wszystkich innych specjalizacji, jak i zdefiniowanie fosobno dla każdej specjalizacji rozwiązuje błąd kompilacji.
Innerjest zgłaszany jako niekompletny typ, pomimo definicji dla każdej specjalizacji Outer. Wyraźnie Innerbędzie (poprawnie) niekompletny, jeśli usuniesz jego definicje.