Дано такий шаблон класу:
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
, що (правильно) буде неповним типом, якщо ви видалите його визначення.