Dado o seguinte modelo de classe:
template<typename T>
struct Outer
{
struct Inner;
auto f(Inner) -> void;
};
definimos Inner
separadamente para cada especialização de Outer
:
template<>
struct Outer<int>::Inner {};
template<>
struct Outer<double>::Inner {};
e defina a função de membro f
uma 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 Inner
para todas as outras especializações de Outer
:
template<typename T>
struct Outer<T>::Inner {};
ou definindo f
separadamente 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?
Inner
para todas as outras especializações e a definição f
separada para cada especialização resolvem o erro de compilação.
Inner
está sendo relatado como um tipo incompleto, apesar das definições para cada especialização a Outer
ser fornecida. Claramente Inner
(corretamente) será um tipo incompleto se você remover suas definições.