El tipo incompleto no está permitido en una clase, pero sí en una plantilla de clase
El siguiente es un código no válido:
struct foo {
struct bar;
bar x; // error: field x has incomplete type
struct bar{ int value{42}; };
};
int main() { return foo{}.x.value; }
Esto es bastante claro, ya quefoo::bar
se considera incompleto en el punto dondefoo::x
se define
Sin embargo, parece haber una "solución" que hace válida la misma definición de clase:
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; }
Estatrabajo con todos los principales compiladores. Tengo tres preguntas sobre esto:
Es este un código C ++ realmente válido, o simplemente una peculiaridad de los compiladores?Si es un código válido, ¿hay un párrafo en el estándar C ++ que aborde esta excepción?Si es un código válido, ¿por qué es la primera versión (sintemplate
) considerado inválido? Si el compilador puede descubrir la segunda opción, no veo una razón por la cual no podría resolver la primera. Si agrego una especialización 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; }
Una vez más falla al compilar.