2009-12-04 4 views
2

Après avoir lu C++ compile-time string hashing with Boost.MPL, et compte tenu d'un problème que j'ai, ce qui suit est venu à l'esprit.Obtenir le type de modèle sous la forme d'une chaîne

je la classe de base:

template<class Command> 
class Base { 
    typedef Command CommandType; 
} 

Il est censé être une classe de base utilitaire pour les classes Commandes, donc ils ne ont pas besoin de typedef et de déclarer certains membres eux-mêmes, ils seraient tout simplement hérite de Base avec les types auxquels ils se réfèrent. Ils peuvent donc être utilisés comme ceci:

class CommandInstantiatorA : public Base<CommandA> 
{ 
public: 
    static std::string GetID() { return "CommandInstantiatorA "; } 
} 

Cependant, il y a cette autre méthode (GetID) que je ne pouvais pas « créer des modèles à » qui retourne un identifiant unique throught l'application. Je voudrais pouvoir hacher le type passé à la classe Base, donc les autres classes n'auraient qu'à spécifier le type. Quelque chose comme ceci:

template <class Base> 
class Base { 
    typedef boost::hash_value(TO_STRING(Base)) ID; //should also be read as: typedef boost::hash_value("CommandA") ID; 
    ... 
} 

Y at-il une telle macro (to_string) qui donne le résultat « Commanda » dans le dernier exemple. Y at-il quelque chose dans Boost.MPL qui peut le faire?

Répondre

7

Non coup de pouce, mais il est juste une partie de C++, donc j'espère que ça va faire - peut-être que vous pourriez envisager d'utiliser RTTI - par exemple comme celui-ci http://en.wikipedia.org/wiki/Typeid

int main() { 
Person person; 
Employee employee; 
Person *ptr = &employee; 
// The string returned by typeid::name is implementation-defined 
std::cout << typeid(person).name() << std::endl; // Person (statically known at compile-time) 
std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time) 
std::cout << typeid(ptr).name() << std::endl;  // Person * (statically known at compile-time) 
std::cout << typeid(*ptr).name() << std::endl;  // Employee (looked up dynamically at run-time 
                //   because it is the dereference of a 
                //   pointer to a polymorphic class) 
} 
+3

Je tiens à souligner que RTTI est disponible uniquement sur la classe avec au moins 1 fonction virtuelle. Pas difficile à concevoir, mais frustrant quand ça ne marche pas et qu'on ne sait pas pourquoi. voir: http://en.wikibooks.org/wiki/C%2B%2B_Programming/RTTI et http://www.cplusplus.com/reference/std/typeinfo/type_info/ – KitsuneYMG

+2

Un autre point, typeid peut être appliqué directement à un type. Ce ne doit pas être une instance. par exemple. typeid (Base) .name() pourrait remplacer TO_STRING dans votre exemple – KitsuneYMG

0

Le préprocesseur (par exemple des macros) ont un opérateur stringizing qui peut envelopper n'importe quel jeton dans les guillemets doubles. Cela ne peut pas faire ce que vous voulez, au moins tel qu'il est écrit, car il va enchaîner le jeton littéral "Base", et non pas le paramètre template-substitué.

1

Vous pouvez utiliser préprocesseur La mise en chaîne - ce résoudre ne probablement pas tout, mais vous pouvez obtenir la chaîne:

#include <iostream> 
using namespace std; 

#define ToString(x) #x 
struct C { static const string id; }; 

const string C::id = ToString(C_ID); 

int main() 
{ 
    C c; 
    cout << c.id << endl; 
} 

Prints:

C_ID