Dado o seguinte modelo de classe:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
definimos Innerseparadamente para cada especialização de Outer:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
e defina a função de membro fuma vez para todas as especializações de Outer:
auto Outer<T>::f(Inner) -> void
{
}
mas Clang (9.0.0) reclama:
error: variable has incomplete type 'Outer::Inner'
auto Outer<T>::f(Inner) -> void
^
Podemos evitar o erro do compilador, fornecendo também uma definição Innerpara todas as outras especializações de Outer:
template<typename T>
struct Outer<T>::Inner {};
ou definindo fseparadamente para cada especialização:
template<>
auto Outer<int>::f(Inner) -> void
{
}
template<>
auto Outer<double>::f(Inner) -> void
{
}
O GCC e o MSVC aceitam o código inicial, o que sugere a pergunta; isso é um bug do Clang ou é a única implementação compatível dos três?
Innerpara todas as outras especializações e a definição fseparada para cada especialização resolvem o erro de compilação.
Innerestá sendo relatado como um tipo incompleto, apesar das definições para cada especialização a Outerser fornecida. Claramente Inner(corretamente) será um tipo incompleto se você remover suas definições.