Estoy trabajando en una biblioteca que a veces incluso utiliza tipos que - jadeo! - ni siquiera están definidos, ¡mucho menos tienen miembros de datos!
Es decir, el tipo es incompleta, como
struct foobar;
Esto se utiliza para crear un nombre inequívoco, nada más.
¿Para qué sirve esto? Bueno, lo usamos para crear distintos etiquetas, utilizando un tipo adicional (vacío, pero totalmente definido):
template <typename TSpec>
struct Tag { };
Ahora puede crear etiquetas distintas, así:
struct TagForward_;
typedef Tag<TagForward_> ForwardTag;
struct TagRandomAccessible_;
typedef Tag<TagRandomAccessible_> RandomAccessibleTag;
Estos a su vez se puede usar para eliminar ambigüedades de sobrecargas especializadas. Muchas implementaciones STL hacen algo similar:
template <typename Iter>
void sort(Iter begin, Iter end, RandomAccessibleTag const&) …
En sentido estricto, la ruta indirecta a través de una plantilla común Tag
clase es redundante, pero que era un truco útil para el bien de la documentación.
Todo esto solo para mostrar que un sistema de tipo (estricto, estático) se puede usar de muchas formas distintas a solo agrupar y encapsular datos.
no todas las clases tienen un vtable, por lo que es irrelevante. – tenfour
Tampoco los vtables tienen nada que ver con C++. Son solo una técnica de implementación común (y por lo tanto no tienen nada que ver con el lenguaje) para implementar la herencia (pero no la única). –
La pregunta obvia que me preguntaría es por qué no permitir objetos de tamaño cero. El hecho de que es un tipo único tiene información que se puede usar. –