Comment puis-je utiliser une classe déclarée en avant dans un std :: vector?

Je pensais que vous ne pouviez créer qu’un membre de référence ou de pointeur vers une classe déclarée en aval. Cependant, j’ai été surpris de découvrir cette œuvre:

#include  struct Donkey; struct Cage { std::vector donkeys; }; struct Donkey { }; int main() { Cage c; } 

http://ideone.com/EP0zKR

Comment se fait-il que std::vector puisse être défini avec une classe déclarée en avant? Est-ce standard?

En fait, vous ne pouvez pas.

Le fait que votre programme comstack (ce qui revient à des faits de la mise en œuvre sous-jacente) ne signifie pas qu’il est valide.

Il existe des moments autres que la déclaration d’un T* ou d’un T& at où vous pouvez utiliser une déclaration aval ; c’est juste que ce n’est pas l’un d’eux .

C’est un comportement indéfini.

[C ++ 14 / §17.6.4.8] 1 Dans certains cas (fonctions de remplacement, fonctions de gestionnaire, opérations sur les types utilisés pour instancier des composants de modèle de bibliothèque standard), la bibliothèque standard C ++ dépend de composants fournis par un programme C ++. Si ces composants ne répondent pas à leurs exigences, la norme n’impose aucune exigence pour la mise en œuvre.

[C ++ 14 / §17.6.4.8] 2 En particulier, les effets ne sont pas définis dans les cas suivants: […]

  • si un type incomplet (3.9) est utilisé comme argument de modèle lors de l’instanciation d’un composant de modèle, sauf autorisation spécifique de ce composant.

De plus, un type incomplet ne répond pas aux exigences de l’allocateur:

[C ++ 14 / §17.6.3.5] 9 Un allocateur peut contraindre les types sur lesquels il peut être instancié et les arguments pour lesquels son membre de construction peut être appelé. Si un type ne peut pas être utilisé avec un allocateur particulier, la classe d’allocateur ou l’appel à construire peut échouer lors de l’instanciation.

Parce que votre classe a une définition au moment où le vecteur est instancié, ça va. Soyez attentif à cette proposition qui modifiera les exigences de l’allocateur, N4056 Prise en charge de types incomplets minimes pour les conteneurs standard