Pourquoi le C ++ n'a-t-il pas de réflexion?


337

C'est une question quelque peu bizarre. Mes objectifs sont de comprendre la décision de conception du langage et d'identifier les possibilités de réflexion en C ++.

  1. Pourquoi le comité du langage C ++ n'est pas allé vers la mise en œuvre de la réflexion dans le langage? La réflexion est-elle trop difficile dans un langage qui ne fonctionne pas sur une machine virtuelle (comme java)?

  2. Si l'on devait mettre en œuvre la réflexion pour C ++, quels seraient les défis?

Je suppose que les utilisations de la réflexion sont bien connues: les éditeurs peuvent être écrits plus facilement, le code du programme sera plus petit, des maquettes peuvent être générées pour les tests unitaires, etc. Mais ce serait bien si vous pouviez aussi commenter les utilisations de la réflexion.

Réponses:


631

Il y a plusieurs problèmes de réflexion en C ++.

  • C'est beaucoup de travail à ajouter, et le comité C ++ est assez conservateur, et ne passez pas de temps sur de nouvelles fonctionnalités radicales à moins qu'ils ne soient sûrs que cela sera payant. (Une suggestion pour ajouter un système de modules similaire aux assemblages .NET a été faite, et même si je pense qu'il y a un consensus général que ce serait bien d'avoir, ce n'est pas leur priorité absolue pour le moment, et a été repoussé bien après C ++ 0x. La motivation de cette fonctionnalité est de se débarrasser du #includesystème, mais elle permettrait également au moins certaines métadonnées).

  • Vous ne payez pas pour ce que vous n'utilisez pas. C'est l'une des philosophies de conception de base incontournables sous-jacentes au C ++. Pourquoi mon code devrait-il transporter des métadonnées si je n'en ai jamais besoin? De plus, l'ajout de métadonnées peut empêcher le compilateur d'optimiser. Pourquoi devrais-je payer ce coût dans mon code si je n'ai jamais besoin de ces métadonnées?

  • Ce qui nous amène à un autre gros point: C ++ fait très peu de garanties sur le code compilé. Le compilateur est autorisé à faire à peu près tout ce qu'il veut, tant que la fonctionnalité résultante est celle attendue. Par exemple, vos cours ne doivent pas nécessairement être là . Le compilateur peut les optimiser loin, incorporer tout ce qu'ils font, et c'est souvent ce que fait, car même un code de modèle simple a tendance à créer pas mal d'instanciations de modèle. La bibliothèque standard C ++ s'appuie sur cette optimisation agressive. Les foncteurs ne sont performants que si les frais généraux d'instanciation et de destruction de l'objet peuvent être optimisés. operator[]sur un vecteur est uniquement comparable à l'indexation de tableaux bruts en termes de performances, car l'opérateur entier peut être inséré et donc entièrement supprimé du code compilé. C # et Java offrent de nombreuses garanties sur la sortie du compilateur. Si je définis une classe en C #, alors cette classe existera dans l'assemblage résultant. Même si je ne l'utilise jamais. Même si tous les appels à ses fonctions membres pouvaient être alignés. La classe doit être là pour que la réflexion puisse la trouver. Une partie de cela est atténuée par la compilation de C # en bytecode, ce qui signifie que le compilateur JIT peutsupprimer les définitions de classe et les fonctions en ligne s'il le souhaite, même si le compilateur C # initial ne le peut pas. En C ++, vous n'avez qu'un seul compilateur et il doit générer du code efficace. Si vous étiez autorisé à inspecter les métadonnées d'un exécutable C ++, vous vous attendriez à voir chaque classe qu'il a définie, ce qui signifie que le compilateur devrait conserver toutes les classes définies, même si elles ne sont pas nécessaires.

  • Et puis il y a des modèles. Les modèles en C ++ ne ressemblent en rien aux génériques dans d'autres langages. Chaque instanciation de modèle crée un nouveau type. std::vector<int>est une classe complètement distincte de std::vector<float>. Cela représente de nombreux types différents dans un programme entier. Que devrait voir notre réflexion? Le modèle std::vector ? Mais comment peut-il, puisque c'est une construction de code source, qui n'a aucune signification au moment de l'exécution? Il faudrait voir les classes séparées std::vector<int>et std::vector<float>. Et std::vector<int>::iteratoret std::vector<float>::iterator, même pourconst_iteratoretc. Et une fois que vous entrez dans la métaprogrammation de modèles, vous finissez rapidement par instancier des centaines de modèles, qui sont tous intégrés et supprimés à nouveau par le compilateur. Ils n'ont aucun sens, sauf dans le cadre d'un métaprogramme à la compilation. Est-ce que toutes ces centaines de classes devraient être visibles à la réflexion? Ils devraient le faire, car sinon notre réflexion serait inutile, si elle ne garantit même pas que les classes que j'ai définies seront effectivement . Et un problème secondaire est que la classe de modèle n'existe pas tant qu'elle n'est pas instanciée. Imaginez un programme qui utilise std::vector<int>. Notre système de réflexion doit-il pouvoir voir std::vector<int>::iterator? D'une part, vous vous attendez certainement à cela. C'est une classe importante, et elle est définie en termes de std::vector<int>, ce qui neexistent dans les métadonnées. D'un autre côté, si le programme n'utilise jamais réellement ce modèle de classe d'itérateur, son type n'aura jamais été instancié, et donc le compilateur n'aura pas généré la classe en premier lieu. Et il est trop tard pour le créer au moment de l'exécution, car il nécessite l'accès au code source.

  • Enfin, la réflexion n'est pas aussi vitale en C ++ qu'en C #. La raison est encore une fois, la métaprogrammation de modèle. Il ne peut pas tout résoudre, mais dans de nombreux cas où vous auriez autrement recours à la réflexion, il est possible d'écrire un métaprogramme qui fait la même chose au moment de la compilation. boost::type_traitsest un exemple simple. Vous voulez connaître le type T? Vérifiez son type_traits. En C #, vous devrez pêcher après son type en utilisant la réflexion. La réflexion serait toujours utile pour certaines choses (l'utilisation principale que je peux voir, que la métaprogrammation ne peut pas facilement remplacer, est pour le code de sérialisation généré automatiquement), mais cela entraînerait des coûts importants pour C ++, et ce n'est tout simplement pas nécessaire aussi souvent que cela est dans d'autres langues.

Edit: En réponse aux commentaires:

cdleary: Oui, les symboles de débogage font quelque chose de similaire, en ce sens qu'ils stockent des métadonnées sur les types utilisés dans l'exécutable. Mais ils souffrent également des problèmes que j'ai décrits. Si vous avez déjà essayé de déboguer une version, vous comprendrez ce que je veux dire. Il existe de grandes lacunes logiques dans lesquelles vous avez créé une classe dans le code source, qui a été intégrée dans le code final. Si vous deviez utiliser la réflexion pour quelque chose d'utile, vous en auriez besoin pour être plus fiable et cohérent. En l'état, les types disparaissent et disparaissent presque à chaque compilation. Vous modifiez un tout petit détail, et le compilateur décide de changer les types à incorporer et ceux qui ne le sont pas, en réponse. Comment en extrayez-vous quelque chose d'utile quand vous n'est-il même pas garanti que les types les plus pertinents seront représentés dans vos métadonnées? Le type que vous recherchiez était peut-être là dans la dernière version, mais maintenant il a disparu. Et demain, quelqu'un vérifiera une petite modification innocente à une petite fonction innocente, ce qui rend le type juste assez grand pour qu'il ne soit pas complètement aligné, il sera donc de retour. C'est toujours utile pour les symboles de débogage, mais pas beaucoup plus que cela. Je détesterais essayer de générer du code de sérialisation pour une classe selon ces termes. mais pas beaucoup plus que ça. Je détesterais essayer de générer du code de sérialisation pour une classe selon ces termes. mais pas beaucoup plus que ça. Je détesterais essayer de générer du code de sérialisation pour une classe selon ces termes.

Evan Teran: Bien sûr, ces problèmes pourraient être résolus. Mais cela revient à mon point n ° 1. Cela prendrait beaucoup de travail, et le comité C ++ a beaucoup de choses qu'ils jugent plus importantes. L'avantage d'obtenir une réflexion limitée (et ce serait limité) en C ++ est-il vraiment assez grand pour justifier de se concentrer sur cela au détriment d'autres fonctionnalités? Y a-t-il vraiment un énorme avantage à ajouter des fonctionnalités au langage de base qui peuvent déjà (pour la plupart) être effectuées via des bibliothèques et des préprocesseurs comme QT? Peut-être, mais le besoin est beaucoup moins urgent que si de telles bibliothèques n'existaient pas. Pour vos suggestions spécifiques, je pense que le refuser sur les modèles le rendrait complètement inutile. Vous ne pourriez pas utiliser la réflexion sur la bibliothèque standard, par exemple. Quel genre de réflexion ne ferait passtd::vector? Les modèles sont une partie énorme de C ++. Une fonctionnalité qui ne fonctionne pas sur les modèles est fondamentalement inutile.

Mais vous avez raison, une forme de réflexion pourrait être mise en place. Mais ce serait un changement majeur dans la langue. Comme c'est le cas actuellement, les types sont exclusivement une construction au moment de la compilation. Ils existent pour le bénéfice du compilateur, et rien d'autre. Une fois le code compilé, il n'y a plus de classes. Si vous vous étirez, vous pourriez faire valoir que les fonctions existent toujours, mais vraiment, tout ce qu'il y a est un tas d'instructions d'assemblage de saut, et beaucoup de push / pop de pile. Il n'y a pas grand-chose à faire lors de l'ajout de telles métadonnées.

Mais comme je l'ai dit, il y a une proposition de changements au modèle de compilation, l'ajout de modules autonomes, le stockage de métadonnées pour certains types, permettant à d'autres modules de les référencer sans avoir à jouer avec #includes. C'est un bon début, et pour être honnête, je suis surpris que le comité de normalisation n'ait pas simplement rejeté la proposition parce qu'elle constituait un changement trop important. Alors peut-être dans 5 à 10 ans? :)


2
La plupart de ces problèmes ne doivent-ils pas déjà être résolus par des symboles de débogage? Non pas que ce serait performant ( en raison de l'inline et l' optimisation que vous avez mentionné), mais vous pouvez permettre la possibilité d' une réflexion en faisant tout symboles de débogage font.
cdleary

2
Une autre chose à propos de votre premier point: pour autant que je sache, personne n'a essayé d'ajouter de la réflexion à une implémentation C ++. Il n'y a pas de bonne expérience avec ça. Le Comité sera probablement réticent à prendre les devants, en particulier après exportet vector<bool>.
David Thornley

18
Je suis d'accord que C ++ ne devrait pas avoir de réflexion sur le temps d'exécution. Mais la réflexion sur le temps de compilation présente quelques-uns des problèmes ci-dessus et pourrait être utilisée par quelqu'un pour construire une réflexion sur le temps d'exécution sur des classes particulières s'il le souhaite. Pouvoir accéder au type, au nom et aux fonctionnalités de la nième méthode et du nième parent d'une classe via un modèle? Et en obtenir le nombre au moment de la compilation? Rendrait possible la réflexion automatique basée sur CRTP, alors que personne ne paie pour ce qu'il n'utilise pas.
Yakk - Adam Nevraumont

15
Votre troisième point est à bien des égards le plus important: C ++ est conçu pour convenir à l'écriture de code autonome sur des plates-formes où la mémoire coûte de l'argent; si l'élimination d'un code inutilisé permettrait à un programme de s'insérer dans un microcontrôleur qui coûte 2,00 $, plutôt que celui qui coûte 2,50 $, et si le code se vend en 1000000 unités, l'élimination de ce code peut économiser 500000 $. Sans réflexion, l'analyse statique peut souvent identifier 90% + de code inaccessible; si la réflexion est autorisée, tout ce qui peut être atteint via la réflexion doit être présumé accessible, même si 90% ne le sont pas.
supercat

2
il y a certainement quelque chose qui peut être amélioré facilement par le comité, c'est enfin dire noir sur blanc que typeinfola name()fonction DOIT retourner le nom qui a été tapé par le programmeur et pas quelque chose d'indéfini. Et donnez-nous aussi un stringifier pour les énumérateurs. Ceci est en fait crucial pour la sérialisation / désérialisation, aider à fabriquer des usines, etc.
v.oddou

38

La réflexion nécessite que certaines métadonnées sur les types soient stockées quelque part qui peuvent être interrogées. Étant donné que C ++ compile en code machine natif et subit de lourdes modifications en raison de l'optimisation, une vue de haut niveau de l'application est quasiment perdue lors du processus de compilation, par conséquent, il ne sera pas possible de les interroger au moment de l'exécution. Java et .NET utilisent une représentation de très haut niveau dans le code binaire pour les machines virtuelles permettant ce niveau de réflexion. Dans certaines implémentations C ++, cependant, il existe quelque chose appelé Run Time Type Information (RTTI) qui peut être considéré comme une version allégée de la réflexion.


15
RTTI est dans la norme C ++.
Daniel Earwicker

1
Mais toutes les implémentations C ++ ne sont pas standard. J'ai vu des implémentations qui ne prennent pas en charge RTTI.
Mehrdad Afshari

3
Et la plupart des implémentations qui prennent en charge RTTI prennent également en charge la désactivation via les options du compilateur.
Michael Kohne,

21

Toutes les langues ne devraient pas essayer d'incorporer toutes les fonctionnalités de toutes les autres langues.

C ++ est essentiellement un assembleur de macros très, très sophistiqué. Ce n'est PAS (au sens traditionnel) un langage de haut niveau comme C #, Java, Objective-C, Smalltalk, etc.

Il est bon d'avoir différents outils pour différents emplois. Si nous n'avons que des marteaux, tout ressemblera à des clous, etc. les langages dépouillés efficaces proches de la machine sont utiles pour une autre classe de travaux (C ++, C, assembleur).

C ++ fait un travail incroyable en étendant la technologie Assembler à des niveaux incroyables de gestion de la complexité et des abstractions pour rendre la programmation plus vaste et plus complexe pour les êtres humains. Mais ce n'est pas nécessairement un langage qui convient le mieux à ceux qui abordent leur problème dans une perspective strictement de haut niveau (Lisp, Smalltalk, Java, C #). Si vous avez besoin d'une langue avec ces fonctionnalités pour implémenter au mieux une solution à vos problèmes, alors remerciez ceux qui ont créé ces langues pour nous tous!

Mais C ++ est destiné à ceux qui, pour une ou plusieurs raisons, ont besoin d'avoir une forte corrélation entre leur code et le fonctionnement de la machine sous-jacente. Que ce soit son efficacité, ou les pilotes de périphériques de programmation, ou l'interaction avec les services de système d'exploitation de niveau inférieur, ou autre, C ++ est mieux adapté à ces tâches.

C #, Java, Objective-C nécessitent tous un système d'exécution beaucoup plus grand et plus riche pour prendre en charge leur exécution. Ce runtime doit être fourni au système en question - préinstallé pour prendre en charge le fonctionnement de votre logiciel. Et cette couche doit être maintenue pour divers systèmes cibles, personnalisée par QUELQUES AUTRES LANGUES pour la faire fonctionner sur cette plate-forme. Et cette couche intermédiaire - cette couche adaptative entre le système d'exploitation hôte et votre code - le runtime, est presque toujours écrite dans un langage comme C ou C ++ où l'efficacité est n ° 1, où la compréhension prévisible de l'interaction exacte entre logiciel et matériel peut être bien compris et manipulé au maximum.

J'adore Smalltalk, Objective-C et avoir un système d'exécution riche avec réflexion, métadonnées, collecte de déchets, etc. Un code incroyable peut être écrit pour tirer parti de ces fonctionnalités! Mais il s'agit simplement d'une couche supérieure de la pile, une couche qui doit reposer sur des couches inférieures, qui elles-mêmes doivent finalement reposer sur le système d'exploitation et le matériel. Et nous aurons toujours besoin d'un langage qui convient le mieux à la construction de cette couche: C ++ / C / Assembler.

Addendum: C ++ 11/14 continue d'étendre la capacité de C ++ à prendre en charge les abstractions et les systèmes de niveau supérieur. Le threading, la synchronisation, des modèles de mémoire précis, des définitions de machines abstraites plus précises permettent aux développeurs C ++ de réaliser de nombreuses abstractions de haut niveau sur lesquelles certains de ces langages de haut niveau uniquement avaient un domaine exclusif, tout en continuant à fournir des performances métalliques et excellente prévisibilité (c.-à-d. sous-systèmes d'exécution minimaux). Peut-être que les fonctionnalités de réflexion seront activées de manière sélective dans une future révision de C ++, pour ceux qui le souhaitent - ou peut-être qu'une bibliothèque fournira de tels services d'exécution (peut-être qu'il y en a un maintenant, ou les débuts d'un dans boost?).


Votre point sur l'exécution d'un langage devant être compilé dans un autre langage n'est pas vrai dans le cas d'Objective-C, car son exécution est écrite en C (dont Objective-C est un sur-ensemble).
Richard J. Ross III

C'est une distinction sans différence. Quelle différence cela fait-il, au final, que le sous-système d'exécution utilisé par Objective-C ne soit en fait pas écrit en Objective-C, mais plutôt en C?
Mordachai

3
Je suis désolé; mais tant que vous le liez correctement, vous pouvez compiler un programme objective-c en C, en fait je l'ai fait ici: stackoverflow.com/a/10290255/427309 . Votre déclaration ci-dessus est fausse. Le runtime est entièrement accessible via C, et c'est l'une des choses qui en fait un langage dynamique si puissant.
Richard J. Ross III

1
Le "runtime C" est juste une bibliothèque dynamique contenant le code de la bibliothèque standard C. Idem pour le "runtime C ++". C'est assez différent d'un système d'exécution comme celui d'Objective-C. Aussi ... alors que je suppose que vous pourriez techniquement utiliser le runtime Objective-C en C, ce n'est encore qu'un programme C qui utilise le runtime Objective-C - vous ne pouvez pas compiler un programme Objective-C réel en C.
celticminstrel

2
C ++ 11 ayant un modèle de mémoire + atomique le fait plus comme un assembleur portable. Ce ne sont pas des choses de haut niveau, ce sont des choses de bas niveau pour lesquelles C ++ manquait auparavant de support portable. Mais la quantité d'UB en C ++ si vous faites quelque chose de mal le rend très différent des langages basés sur des machines virtuelles comme Java et également différent de tout langage d'assemblage spécifique. Par exemple, le débordement signé est totalement UB dans la source C ++ et le compilateur peut optimiser en fonction de ce fait même si la compilation pour disons x86, mais en asm sur presque toutes les plates-formes, il ne fera que boucler. Le C ++ moderne est très loin d'un langage d'assemblage portable.
Peter Cordes

11

Si vous voulez vraiment comprendre les décisions de conception entourant C ++, trouvez une copie du Manuel de référence Annotated C ++ par Ellis et Stroustrup. Ce n'est PAS à jour avec la dernière norme, mais elle passe par la norme d'origine et explique comment les choses fonctionnent et souvent, comment elles sont arrivées de cette façon.


6
Également Conception et évolution de C ++ par Stroustrup
James Hopkin

9

La réflexion pour les langages qui en dépendent concerne la quantité de code source que le compilateur est prêt à laisser dans votre code objet pour permettre la réflexion, et la quantité de machines d'analyse disponibles pour interpréter ces informations réfléchies. À moins que le compilateur ne conserve tout le code source, la réflexion sera limitée dans sa capacité à analyser les faits disponibles sur le code source.

Le compilateur C ++ ne garde rien (enfin, en ignorant RTTI), donc vous n'obtenez pas de réflexion dans le langage. (Les compilateurs Java et C # ne conservent que les noms de classe, de méthode et de retour, vous obtenez donc un peu de données de réflexion, mais vous ne pouvez pas inspecter les expressions ou la structure du programme, ce qui signifie que même dans ces langages les informations que vous pouvez obtenir sont assez rares et, par conséquent, vous ne pouvez vraiment pas faire beaucoup d'analyses).

Mais vous pouvez sortir du langage et bénéficier de capacités de réflexion complètes. La réponse à une autre discussion de débordement de pile sur la réflexion en C en discute.


7

La réflexion peut être et a été implémentée en c ++ auparavant.

Ce n'est pas une fonctionnalité native C ++ car elle a un coût élevé (mémoire et vitesse) qui ne devrait pas être défini par défaut par la langue - la langue est orientée "performances maximales par défaut".

Comme vous ne devriez pas payer pour ce dont vous n'avez pas besoin, et comme vous le dites vous-même, il est plus nécessaire dans les éditeurs que dans d'autres applications, il ne devrait être implémenté que là où vous en avez besoin, et non "forcé" à tout le code ( vous n'avez pas besoin de réfléchir à toutes les données avec lesquelles vous travaillerez dans un éditeur ou une autre application similaire).


3
et vous n'envoyez pas de symboles car cela permettrait à vos clients / concurrents de regarder votre code ... c'est souvent considéré comme une mauvaise chose.
gbjbaanb

Vous avez raison, je n'ai même pas
pensé au

6

La raison pour laquelle C ++ n'a pas de réflexion est que cela obligerait les compilateurs à ajouter des informations de symboles aux fichiers objets, comme les membres d'un type de classe, les informations sur les membres, les fonctions et tout. Cela rendrait essentiellement les fichiers include inutiles, car les informations fournies par les déclarations seraient alors lues à partir de ces fichiers objets (modules ensuite). En C ++, une définition de type peut se produire plusieurs fois dans un programme en incluant les en-têtes respectifs (à condition que toutes ces définitions soient identiques), il faudrait donc décider où mettre les informations sur ce type, tout comme pour en nommer un complication ici. L'optimisation agressive effectuée par un compilateur C ++, qui peut optimiser des dizaines d'instanciations de modèles de classe, est un autre point fort. C'est possible, mais comme C ++ est compatible avec C,


1
Je ne comprends pas en quoi l'optimisation agressive du compilateur est un point fort. Peux-tu élaborer? Si l'éditeur de liens peut supprimer les définitions de fonction en ligne en double, quel est le problème avec les informations de réflexion en double? De toute façon, les informations de symbole ne sont-elles pas ajoutées aux fichiers objets, pour les débogueurs?
Rob Kennedy

1
Le problème est que vos informations de réflexion peuvent être invalides. Si le compilateur élimine 80% de vos définitions de classe, que diront vos métadonnées de réflexion? En C # et Java, le langage garantit que si vous définissez une classe, elle reste définie. C ++ permet au compilateur de l'optimiser.
jalf

1
@Rob, les optimisations sont un autre point, non lié à la complication de plusieurs classes. Voir le commentaire de @ jalf (et sa réponse) pour ce que je voulais dire.
Johannes Schaub - litb

4
Si j'instancie reflète <T>, alors ne jetez aucune information de T. Cela ne semble pas être un problème insoluble.
Joseph Garvin

3

Il existe des tonnes de cas d'utilisation de la réflexion en C ++ qui ne peuvent pas être traités de manière adéquate en utilisant des constructions de temps de compilation comme la méta-programmation de modèles.

N3340 propose des pointeurs riches comme moyen d'introduire la réflexion en C ++. Entre autres choses, il résout le problème du non-paiement d'une fonctionnalité à moins que vous ne l'utilisiez.


2

Selon Alistair Cockburn, le sous - typage ne peut pas être garanti dans un environnement réfléchissant .

La réflexion est plus pertinente pour les systèmes de typage latents. En C ++, vous savez de quel type vous disposez et vous savez ce que vous pouvez en faire.


Plus généralement, la possibilité de vérifier l'existence d'une fonctionnalité qui n'existe pas sans introduire un comportement indéfini permet que l'ajout de cette fonctionnalité à une version ultérieure d'une classe modifie le comportement bien défini des programmes préexistants et par conséquent, il est impossible de garantir que l'ajout de cette fonctionnalité ne «cassera» pas quelque chose.
supercat

2

La réflexion peut être facultative, comme une directive de préprocesseur. Quelque chose comme

#pragma enable reflection

De cette façon, nous pouvons avoir le meilleur des deux mondes, sans que ces bibliothèques de pragma soient créées sans réflexion (sans frais généraux comme discuté), alors ce serait au développeur individuel s'il veut la vitesse ou la facilité d'utilisation.


2

Si C ++ pouvait avoir:

  • données de membre de classe pour les noms de variables, les types de variables et le constmodificateur
  • un itérateur d'arguments de fonction (uniquement la position au lieu du nom)
  • données de membre de classe pour les noms de fonction, le type de retour et le constmodificateur
  • liste des classes parentes (dans le même ordre que défini)
  • données pour les membres du modèle et les classes parentes; le modèle étendu (ce qui signifie que le type réel serait disponible pour l'API de réflexion et non les `` informations sur le modèle pour savoir comment y arriver '')

Cela suffirait à créer des bibliothèques très faciles à utiliser au cœur du traitement de données sans type qui est si répandu dans les applications Web et de base de données d'aujourd'hui (tous les orms, mécanismes de messagerie, analyseurs xml / json, sérialisation des données, etc.).

Par exemple, les informations de base prises en charge par la Q_PROPERTYmacro (faisant partie de Qt Framework) http://qt.nokia.com/doc/4.5/properties.html développées pour couvrir les méthodes de classe et e) - seraient extrêmement bénéfiques pour C ++ et pour la communauté des logiciels en général.

Certes, la réflexion à laquelle je fais référence ne couvrirait pas la signification sémantique ou les questions plus complexes (comme les numéros de ligne de code source des commentaires, l'analyse des flux de données, etc.) - mais je ne pense pas non plus que ces éléments soient nécessaires pour faire partie d'une norme de langage.


@Vlad: Oui, si l'on ajoute des fonctionnalités soutenant la réflexion à la langue, vous obtenez la réflexion dans la langue. Cela ne se produira probablement que si le comité des langues le décrète, et je pense qu'ils ne l'ont pas fait en 2011, et je doute qu'il y ait une autre norme C ++ avant 2020 après JC. Alors, belle pensée. En attendant, si vous voulez progresser, vous devrez probablement sortir du C ++.
Ira Baxter


0

La réflexion en C ++, je crois est d'une importance cruciale si le C ++ doit être utilisé comme langage pour l'accès à la base de données, la gestion des sessions Web / http et le développement de l'interface graphique. Le manque de réflexion empêche les ORM (comme Hibernate ou LINQ), les analyseurs XML et JSON qui instancient les classes, la sérialisation des données et bien d'autres thigns (où des données initialement sans type doivent être utilisées pour créer une instance d'une classe).

Un commutateur de temps de compilation disponible pour un développeur de logiciels pendant le processus de construction peut être utilisé pour éliminer cette préoccupation «vous payez pour ce que vous utilisez».

Si un développeur de micrologiciel n'a pas besoin de la réflexion pour lire les données d'un port série, alors n'utilisez pas le commutateur. Mais en tant que développeur de base de données qui souhaite continuer à utiliser C ++, je suis constamment en phase avec un code horrible et difficile à maintenir qui mappe les données entre les membres de données et les constructions de base de données.

Ni la sérialisation Boost ni aucun autre mécanisme ne résolvent vraiment la réflexion - cela doit être fait par le compilateur - et une fois cela fait, le C ++ sera à nouveau enseigné dans les écoles et utilisé dans les logiciels traitant du traitement des données.

Pour moi, ce problème # 1 (et les primitives de threading naitive est le problème # 2).


4
Qui a dit que C ++ est d'être utilisé comme langue pour DB Access, la session Web hnadling ou dev IUG? Il y a beaucoup de langues bien meilleures à utiliser pour ce genre de choses. Et un commutateur de compilation ne résoudra pas le problème. Habituellement, la décision d'activer ou de désactiver la réflexion ne se fera pas par fichier. Cela pourrait fonctionner s'il pouvait être activé sur des types individuels. Si le programmeur peut spécifier avec un attribut ou similaire lors de la définition d'un type, si des métadonnées de réflexion pour celui-ci doivent être générées. Mais un changement global? Vous seriez en train de paralyser 90% de la langue juste pour en simplifier 10%.
jalf

Ensuite, si je veux un programme multiplateforme et avoir accès à une interface graphique, que dois-je utiliser? L'oscillation inflexible de Java? Les fenêtres uniquement C #? Mais la vérité doit être dite, et la vérité est qu'il existe de nombreux programmes qui sont compilés en code exécutable, et offrent une interface graphique et un accès aux bases de données, ils doivent donc utiliser une base de données et un support graphique ... Et ils ne sont pas '' t en utilisant QT. (il aurait dû être nommé MT (boîte à outils monstre))
Coyote21

1
@ Coyote21: C # n'a pas été Windows uniquement depuis des années. (Bien que je ne sois pas fan de Mono, cela fonctionne assez bien pour la plupart des choses.) Et Swing n'est pas la seule boîte à outils GUI pour Java. À vrai dire, l'un ou l'autre serait un meilleur choix si vous voulez multiplateforme. C ++ aura à peu près toujours des parties spécifiques à la plate-forme ici ou là si vous faites quelque chose de non trivial.
cHao

Il n'y a aucune raison pour laquelle vous avez besoin de réflexion pour l'ORM. Vous pouvez réaliser tout cela avec des modèles. Il y a un tas de frameworks qui fournissent ORM pour C ++.
MrFox

0

C'est essentiellement parce que c'est un "extra facultatif". Beaucoup de gens choisissent C ++ plutôt que des langages comme Java et C # pour avoir plus de contrôle sur la sortie du compilateur, par exemple un programme plus petit et / ou plus rapide.

Si vous choisissez d'ajouter une réflexion, différentes solutions sont disponibles .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.