9
votes

C ++ simple réflexion simple sans macros: Nom de la variable d'impression et sa valeur

Y a-t-il une manière non macro-macro-up dans C ++ d'impression d'un nom variable avec sa valeur. Voici la macroide:

#define SHOW(a) std::cout << #a << ": " << (a) << std::endl


3 commentaires

Pourquoi en avez-vous besoin sans macro? Vous voulez le faire en cours d'exécution?


@Balki: Comment ça compte?


@baiki, non, pas d'exécution, mais je veux éviter d'utiliser des macros dans ce cas (et en général) en raison de collisions de noms et de manque de fonctionnalités de surcharge.


5 Réponses :


6
votes

Non, c ++ ne supporte pas la réflexion et le seul moyen de le faire (autant que je sache) sont avec des macros.


3 commentaires

Au fait, je suis bien conscient que C ++ n'appuie pas de manière native la réflexion, cependant, je pensais que certaines solutions puissantes ne sont pas multiples dans la plate-forme qui ne le savaient pas.


@Lex: Je me rends compte que; C'est pourquoi j'ai spécifiquement mentionné que ce n'est pas possible sans macros (votre seule contrainte).


@Alanturing Reflet dans d'autres langues s'appuie probablement sur les macros à un niveau. Python lui-même est une macro. Appelez-le par un autre nom, mais une couche d'interprétation ou une compilation intermédiaire accorde des propriétés similaires aux macros.



0
votes

aucun moyen.

sans macro, vous devez le faire: xxx

pas d'autre moyen.


0 commentaires

0
votes

Si vous pouvez obtenir toutes vos classes dérivent d'un ancêtre commun, vous pouvez fournir une fonction virtuelle qui l'accomplit. Je n'ai pas essayé ce modèle, cela pourrait ne pas fonctionner - certains commentaires seraient appréciés. XXX


1 commentaires

Je ne sais pas si la cout de * Ce fonctionnera sans définir opérateur <<< / code> sur la classe. Je voudrais implémenter show () dans la classe de base et la force (via une méthode abstraite pure dans la classe de base) les sous-classes pour définir opérateur <<< / code> ou une sorte de méthode de tostring .



3
votes

Vous pouvez utiliser des symboles dynamiques, mais il ne fonctionnera que dans les bibliothèques partagées ou les exécutables compilés avec le drapeau -RDYNAMIC. Et il reconnaîtra juste des variables globales avec une visibilité dynamique par défaut.

#include <dlfcn.h>
#include <iostream>

int NameMe = 42;

const char *GetName(const void *ptr)
{
    Dl_info info;
    if (dladdr(ptr, &info))
        return info.dli_sname;
    else
        return NULL;
}

    template<typename T>
void Dump(const T &t)
{
    const char *name = GetName(&t);
    if (name)
        std::cout << name;
    else
        std::cout << "<unknown>";
    std::cout << ": " << t << std::endl;
}
int main()
{
    int NoName = 33;
    Dump(NameMe);
    Dump(NoName);
    return 0;
}

$ g++ dump.cpp -ldl -rdynamic
$ ./a.out
NameMe: 42
<unknown>: 33


0 commentaires

0
votes

oui; En C ++ 17, vous pouvez utiliser PFR (en mode C ++ 17) pour obtenir des niveaux non provisoires de réflexion non macro. Il existe des mécanismes connexes pour refléter la "valeur de la chaîne" d'un énumé.

  1. Voir https://github.com/apolukhin/magic_get ;
  2. et https://github.com/nargye/magic_enum .

0 commentaires