Tipo incompleto não é permitido em uma classe, mas é permitido em um modelo de classe
O código a seguir é inválido:
struct foo {
struct bar;
bar x; // error: field x has incomplete type
struct bar{ int value{42}; };
};
int main() { return foo{}.x.value; }
Isso é bem claro, poisfoo::bar
é considerado incompleto no ponto em quefoo::x
é definido.
No entanto, parece haver uma "solução alternativa" que torna válida a mesma definição de classe:
template <typename = void>
struct foo_impl {
struct bar;
bar x; // no problems here
struct bar{ int value{42}; };
};
using foo = foo_impl<>;
int main() { return foo{}.x.value; }
estetrabalho com todos os principais compiladores. Eu tenho três perguntas sobre isso:
É realmente um código C ++ válido ou apenas uma peculiaridade dos compiladores?Se for um código válido, existe um parágrafo no padrão C ++ que lide com essa exceção?Se for um código válido, por que a primeira versão (semtemplate
) considerado inválido? Se o compilador puder descobrir a segunda opção, não vejo uma razão para não conseguir descobrir a primeira.Se eu adicionar uma especialização explícita paravoid
:
template <typename = void>
struct foo_impl {};
template<>
struct foo_impl<void> {
struct bar;
bar x; // error: field has incomplete type
struct bar{ int value{42}; };
};
using foo = foo_impl<>;
int main() { return foo{}.x.value; }
Mais uma vezfalha ao compilar.