40 votes

Est std::vector<T> « user-defined type » ?</T>

Dans 17.6.4.2.1/1 et 17.6.4.2.1/2 de l' actuel projet de norme restrictions sont placées sur les spécialisations injecté par les utilisateurs en namespace std.

Le comportement d'un C ++ le programme n'est pas défini si on ajoute les déclarations ou les définitions de l'espace de noms std ou à un espace de noms au sein de l'espace de noms std à moins d'indication contraire. Un programme peut ajouter un modèle de spécialisation pour toute bibliothèque standard du modèle de l'espace de noms std seulement si la déclaration dépend d'un type défini par l'utilisateur et de la spécialisation répond à la norme de la bibliothèque exigences pour le modèle d'origine et n'est pas explicitement l'interdit.

Je ne trouve pas où dans le standard de la phrase type défini par l'utilisateur est défini.

Une option que j'ai entendu revendiquée est qu'un type qui n'est pas std::is_fundamental est un type défini par l'utilisateur, auquel cas std::vector<int> serait un type défini par l'utilisateur.

Une alternative réponse serait qu'un type défini par l'utilisateur est un type que l'utilisateur définit. Comme les utilisateurs ne définissent pas d' std::vector<int>, et std::vector<int> ne dépend pas de n'importe quel type d'un utilisateur définit, std::vector<int> n'est pas un type défini par l'utilisateur.

Un problème pratique, cet impact est "pouvez-vous injecter une spécialisation pour std::hash pour std::tuple<Ts...> en namespace std? Être en mesure de le faire est peu pratique-l'alternative est de créer un autre espace de noms où nous récursivement construire notre hachage std::tuple (et éventuellement d'autres types d' std qui n'ont pas d' hash de soutien), et si et seulement si nous ne parvenons pas à trouver un hash dans cet espace de noms ne nous rabattre sur l' std.

Cependant, si c'est légal, alors, si et lorsque la norme ajoute un hash spécialisation pour std::tuple de namespace std, code spécialisé, il serait déjà cassé, la création d'une raison de ne pas ajouter de telles spécialisations dans l'avenir.

Alors que je parle d' std::vector<int> comme un exemple concret, je suis en train de vous demander si les types définis dans le std sont jamais définis par l'utilisateur de type s. Une question secondaire, même si ce n'est, peut - std::tuple<int> devient un type défini par l'utilisateur lorsqu'il est utilisé par un utilisateur (cela devient glissante: alors qu'advient-il si quelque chose à l'intérieur d' std définit std::tuple<int>, et vous partielles se spécialisent hash pour std::tuple<Ts...>).

33voto

Daniel Frey Points 30752

Prof. Stroustrup est très clair qu'un type qui n'est pas intégré est défini par l'utilisateur. Voir le deuxième alinéa de l'article 9.1 de la Programmation des Principes et Pratique avec C++.

Il a même spécifiquement appelle "standard de la bibliothèque de types" comme un exemple de types définis par l'utilisateur. En d'autres termes, un type défini par l'utilisateur est un composé de type.

Source

L'article mentionne explicitement que pas tout le monde semble d'accord, mais c'est à mon humble avis, la plupart des réalités et non pas ce que la norme (et prof. Stroustrup) sont en train de dire, seulement ce que certaines personnes veulent lire en elle.

7voto

Nikos Athanasiou Points 7015

Comme les utilisateurs ne définissent pas d' std::vector<int>, et std::vector<int> ne dépend pas de n'importe quel type d'un utilisateur définit, std::vector<int> n'est pas un type défini par l'utilisateur.

La logique de contre-argument est que les utilisateurs ne définissent std::vector<int>. Vous voyez std::vector est un modèle de classe et n'a pas de représentation directe dans le code binaire.

Dans un sens il obtient représentation binaire par le biais de l'instanciation d'un type, de sorte que l'action de la déclaration d'un std::vector<int> objet est ce qui donne à "l'âme" pour le modèle (pardon pour le phrasé). Dans un programme où personne n'utilise un std::vector<int> ce type de données n'existe pas.

Sur l'autre main, en suivant le même argument, std::vector<T> est pas un type défini par l'utilisateur, il n'est même pas un type, il n'existe pas, que si nous le voulons (instancier un type), il sera mandat quelle structure va être posées, mais jusqu'alors nous ne pouvons argumenter à ce sujet en termes de structure, la conception, les propriétés et ainsi de suite.

Note

L'argument ci-dessus (sur les modèles n'étant pas de code mais ... bien des modèles pour le code) peut paraître un peu superficielle, mais attire c'est de la logique, de la Mayer de l'introduction en A. Alexandrescu du livre Modern C++ Design. La relative citation là, qui va comme ceci :

Finalement, Andrei tourné son attention vers le développement d'un modèle basé sur les implémentations de la langue populaire des idiomes et des modèles de conception, en particulier le GoF[*] les modèles. Cela a conduit à une brève escarmouche avec les Modèles de la communauté, parce que l'un de leurs principes fondamentaux est que les modèles ne peuvent pas être représentés dans le code. Une fois qu'il est devenu clair qu'Andrei a été l'automatisation de la génération de modèle implémentations plutôt que d'essayer de coder les modèles eux-mêmes, que l'objection a été supprimé, et j'ai été heureux de voir Andrei et l'un des GoF (John Vlissides) de collaborer sur deux colonnes dans le C++ Rapport mettant l'accent sur Andrei du travail.

2voto

n.m. Points 30344

Le projet de norme contrastes fondamentaux types de types définis par l'utilisateur dans un couple de (non normatif) des lieux.

Le projet de norme utilise également le terme "utilisateur" dans d'autres contextes, se référant à des entités créées par le programmeur ou définis dans la bibliothèque standard. Les exemples incluent définis par l'utilisateur constructeur, opérateur défini par l'utilisateur et de conversion définie par l'utilisateur.

Ces faits nous permettent, en l'absence d'autres preuves, pour essayer d'assumer que l'objectif de la norme est que le type défini par l'utilisateur doit dire composé de type, selon l'historique de l'utilisation. Seulement une précision explicite dans un futur standard de document peut certainement résoudre le problème.

Notez que l'historique d'utilisation n'est pas clair sur les types comme int* ou struct foo* ou void(*)(struct foo****). Ils sont composés, mais faut-il (ou certains d'entre eux) comme défini par l'utilisateur?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X