Dada la siguiente plantilla de clase:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
Definimos Inner
por separado para cada especialización de Outer
:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
y luego defina la función miembro f
una vez para todas las especializaciones de Outer
:
auto Outer<T>::f(Inner) -> void
{
}
pero Clang (9.0.0) se queja:
error: variable has incomplete type 'Outer::Inner'
auto Outer<T>::f(Inner) -> void
^
Podemos evadir el error del compilador proporcionando también una definición de Inner
todas las demás especializaciones de Outer
:
template<typename T>
struct Outer<T>::Inner {};
o definiendo por f
separado para cada especialización:
template<>
auto Outer<int>::f(Inner) -> void
{
}
template<>
auto Outer<double>::f(Inner) -> void
{
}
Tanto GCC como MSVC aceptan el código inicial, lo que plantea la pregunta; ¿Es esto un error de Clang o es la única implementación conforme de las tres?
Inner
para todas las otras especializaciones como definir f
por separado para cada especialización resuelve el error de compilación.
Inner
se informa como un tipo incompleto a pesar de las definiciones para cada especialización que Outer
se proporciona. Claramente Inner
(correctamente) será un tipo incompleto si elimina sus definiciones.