Дано такий шаблон класу:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
ми визначаємо Innerокремо для кожної спеціалізації Outer:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
а потім fодин раз визначити функцію члена для всіх спеціалізацій Outer:
auto Outer<T>::f(Inner) -> void
{
}
але Кланг (9.0.0) скаржиться:
error: variable has incomplete type 'Outer::Inner'
auto Outer<T>::f(Inner) -> void
^
Ми можемо уникнути помилки компілятора, надавши також визначення Innerдля всіх інших спеціалізацій Outer:
template<typename T>
struct Outer<T>::Inner {};
або fокремо визначившись для кожної спеціалізації:
template<>
auto Outer<int>::f(Inner) -> void
{
}
template<>
auto Outer<double>::f(Inner) -> void
{
}
І GCC, і MSVC приймають початковий код, який ставить питання; це помилка Clang чи це єдина відповідна реалізація з трьох?
Innerдля всіх інших спеціалізацій, і окремо визначення fдля кожної спеціалізації вирішують помилку компіляції.
Innerвін повідомляється як неповний тип, незважаючи на визначення для кожної спеціалізації, Outerщо надається. Очевидно Inner, що (правильно) буде неповним типом, якщо ви видалите його визначення.