8
votes

Absence d'opérateur de typeOf en C ++ 03?


6 commentaires

C ++ 03 pourrait a fourni beaucoup de choses. Mais la norme était déjà énorme telle qu'elle était, et ils n'étaient pas désireux d'ajouter plus que ce n'était absolument nécessaire. Ils ont donc laissé beaucoup de choses que, par leur propre admission, serait bien d'avoir. Bien sûr, C ++ 0x vous donne déclencher qui résout le problème.


@jalf: Qu'est-ce que je voulais dire par "C ++ 03 aurait pu fournir ..." Est-ce que les compilateurs implémentent déjà Tailleof () , et ce n'est pas possible, à moins que ce soit clairement Découvre le type de l'expression. Cela signifie, afin de fournir typeof () opérateur, les compilateurs n'ont pas besoin de faire des choses supplémentaires. En fait, typeof () est libre avec Tailleof () , comme je pense que ce dernier nécessite plus d'inspection / analyse / travail que le premier.


Il n'y a pas de telle chose que "libre". À tout le moins, il y a des tests supplémentaires à faire. Mais vous sous-estimez également la complexité. Obtenir le type d'expression est assez simple dans le cas simple , mais vous devez prendre beaucoup de décisions sur le point de préserver les qualificateurs de CV et les références, par exemple. DeclType a quelques règles étranges pour faire face à cela. Mais deuxièmement, obtenir le type est la partie facile. Ensuite, vous devez déterminer comment il devrait interagir avec d'autres parties de la langue. Si vous êtes autorisé à faire ceci: std :: vecteur ? Ça ne vient pas "gratuitement"


Mais mon point se tient toujours. Oui, il pourrait avoir été mis en œuvre et que serait utile aurait été utile, mais cela aurait rendu la langue plus grande et plus complexe, et il a déjà pris presque une décennie pour les compilateurs à rattraper le standard tel qu'il est. Ils ont dû dessiner la ligne quelque part. Ils ont également massacré la STL, laissant échapper quelque chose comme deux tiers, tout simplement parce qu'ils ne pouvaient pas se permettre de rendre la langue trop grande.


Juste pour illustrer, taille de lance les références. Si vous invoquez Tailleof sur une variable de type int & , cela vous donne la taille d'un int. Mais devrait typeof sur la même variable renvoie int ou int & ?


@Nawaz: "aurait pu avoir" est toujours une phrase très simplifiée et d'attention qui est facile à afficher par la suite (si elle est destinée à être une déclaration). Peut-être que cela aurait eu si vous auriez été dans le comité alors? Mais techniquement, je suis d'accord.


5 Réponses :


6
votes

De la mémoire, boost :: typeof est implémenté via certains?: Hacks. Premièrement, vous commencez par une classe pouvant être convertie en une autre classe, comme xxx

le?: Les règles indiquent que si les deux parties ont le même type, le résultat est ce type. Sinon, si un type peut être converti à l'autre type, c'est-à-dire le type de résultat. Donc, en faisant xxx

le type de résultat est (une référence constante à) le type d'expr- mais expr n'est jamais réellement évalué, car c'est sur la fausse branche. Alors alors vous le transmettez à un endroit qui a déjà une déduction de l'argument, tels que des arguments de fonction. xxx

ceci est un peu plus complexe car de la mémoire, c ++ 03 ne fonctionne pas avoir une réflexion de référence, il est donc probablement un peu plus compliqué que cet exemple, probablement utilisant des traits de type SFIAE et de type.

Comment cela est converti en un type de compilation réel que vous pouvez passer dans un modèle, i Aucune idée. En ce qui concerne C ++ 03 fournissant DeclType (), bien, il existe des problèmes beaucoup plus importants avec la langue C ++ 03, comme les commandes ODR et la déclaration / Définition, aucune sémantique de déménagement, etc., qui sont bien pires que ne pas fournir DeclType. < / p>


7 commentaires

BTW- Pouvez-vous élaborer comment ODR est un problème avec C ++? J'ai toujours trouvé une règle naturelle, mais il me manque peut-être quelque chose.


@Deadmg: Votre dernier paragraphe n'a pas de sens pour moi. Le sujet concerne typeof . Ainsi, lorsque le compilateur connaît déjà la taille de de type d'une expression, alors il est évident qu'il connaît le type aussi .


@Kos: Parce que vous passez votre vie à dire aux choses du compilateur, il sait déjà que d'autres unités de traduction, ou doivent être déclarées, puis définies, ou toutes les anciennes conneries comme celle-ci, qui est une gaspillage colossale de temps de programmateur. @Nawaz: Ce que je dis, c'est que C ++, 03 ou 0x, a déjà tant de WTFS, qui ne fournissant pas DeclType en 03 est assez faible sur la liste de «Quel était le tabagisme de la commission?».


@Deadmg, je pense que vous mentionnez la nécessité de redécriger quelque chose dans de nombreuses unités de traduction (que je déteste bien); Comment est-ce lié à une règle de définition? Parlons-nous de la même personne d'odr? :)


@Kos: ce n'est pas ça. ODR dit que vous ne pouvez pas définir une fonction non intégrée dans une en-tête. Si vous avez une classe avec une centaine de fonctions membres, vous devez les définir à nouveau dans une unité de traduction, vous forçant à répéter chaque argument, chaque retour Tapez et maintenez le DILIT quand il change. Les déclarations sont une autre WTF tout seul.


@Deadmg, dans ce cas, je dirais que les deux problèmes que nous mentionnons tomber sous un nom: "C / C ++ ont des unités de traduction au lieu de modules".


@Kos: En effet. Contez-vous devant la date de vente de l'unité de traduction.



0
votes

Il est défini comme suit:

#define BOOST_TYPEOF(Expr) \
boost::type_of::decode_begin<BOOST_TYPEOF_ENCODED_VECTOR(Expr) >::type


0 commentaires

11
votes

Il utilise simplement la magie du compilateur. Comme, GCC's __ typeof __ . Pour les compilateurs qui ne fournissent pas une telle magie, il fournit une émulation capable de détecter le type d'expressions , mais échoue avec des types complètement inconnus.

Une implémentation éventuelle pourrait être de disposer d'une liste de fonctions qui acceptent une expression d'un type donné, puis d'expédier de ce type à un numéro à l'aide d'un modèle de classe. Pour que le modèle de fonction renvoie le numéro en tant qu'entité de la compilation, nous le mettons dans une dimension de matrice xxx

alors cela passe de ce numéro au type, de sorte que notre emul_typeof pourrait nommer directement le type. Donc, pour enregistrer un type, nous écrivons xxx

ayant cela en place, vous pouvez écrire xxx

chaque fois que vous avez besoin de enregistrer un type, vous écrivez xxx

bien sûr, vous trouverez maintenant que vous avez besoin d'un mécanisme pour accepter vecteur , où vous ne le faites pas savoir t à l'avance, puis il obtient un complexe arbitraire. Vous pouvez créer un système dans lequel les chiffres signifient plus qu'un simple type. Cela pourrait probablement fonctionner: xxx

Ceci pourrait détecter des types tels que int et également des types tels que partagé_ptr d'autres mots, des types qui ne sont pas des spécialisations de modèle de classe et des spécialisations de modèle de classe avec un argument de modèle, en faisant une sorte de mappage systématique

  • Si le premier numéro donne 1, le deuxième numéro spécifie un type; sinon
  • Le premier numéro spécifie un modèle et le deuxième numéro de son premier type d'argument de modèle

    de sorte que cela devient xxx

    Nous devons également modifier le modèle Dispatch et diviser en deux versions, illustrée ci-dessous. , à côté du register_temp1 pour enregistrer des modèles d'un argument xxx

    enregistrant le modèle std :: vecteur modèle et INT Les variantes ressemblent maintenant à xxx

    Vous souhaitez probablement également enregistrer plusieurs numéros avec chaque type, un chiffre pour chaque combinaison de const / volatile ou peut avoir besoin de plus qu'un nombre par type d'enregistrement * , & et tel. Vous souhaitez également prendre en charge vecteur > , vous avez donc besoin de plusieurs numéros pour l'argument de modèle, rendant également build_type appeler de manière récursive. Comme vous pouvez créer une longue liste d'entiers arbitraires, vous pouvez également encoder n'importe quoi dans cette séquence, donc c'est juste à votre créativité sur la manière de représenter ces choses.

    à la fin, vous êtes probablement réinvestir BOOST_TYPEOF :)


1 commentaires

Vous avez présenté un grand impulsion pour une nouvelle pensée. Merci :-)



0
votes

Depuis que Boost est distribué en tant que code source (et BOOST_TYPEOF disponible est une implémentation de fichier d'en-tête dans tous les cas), vous pouvez bien sûr juste jeter un coup d'oeil. Il possède beaucoup de compilation conditionnelle spécifique du compilateur, de sorte que la réponse est que le compilateur est spécifique.


0 commentaires

0
votes

Bien que pas exactement la même chose que typeof , c ++ 0x a déclinger .


2 commentaires

Comment DeclTyPe n'est-il pas le même que le typeof?


Je sais que c ++ 0x a DeclType, mais ce n'est pas la question ici. Vous devriez écrire une telle chose dans des commentaires.