Get the templated type as a string
After reading C++ compile-time string hashing with Boost.MPL, and considering a problem I have, the following came to my mind.
I have the base class:
template<class Command>
class Base {
typedef Command CommandType;
}
It is supposed to be a utility base class for the Commands classes, so they don't need to typedef and declare some members on their own, they would simply inherit from Base with the types they refer to. So they can be used like this:
class CommandInstantiatorA : public Base<CommandA>
{
public:
static std::string GetID() { return "CommandInstantiatorA "; }
}
However, there is this other method (GetID) which I couldnt "templatize" which returns an unique ID throught the application. I would like to be able to hash the type passed to the class Base, so the other classes would only need to specify the type. Something like this:
template <class Ba开发者_Python百科se>
class Base {
typedef boost::hash_value(TO_STRING(Base)) ID; //should also be read as: typedef boost::hash_value("CommandA") ID;
...
}
Is there such a macro (TO_STRING) that would yield the result "CommandA" in the last example. Is there anything in Boost.MPL that can do this?
Not in boost but it's just part of C++ so I hope it'll do - maybe you could consider using RTTI - for example like this 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)
}
You can use preprocessor stringification - this probably does not solve everything but you can get the string:
#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
The preprocessor (i.e. macros) have a stringizing operator that can wrap any token in double quote marks. This can't do what you want, at least as written, because it'll stringize the literal token "Base", and not the substituted-in template parameter.
精彩评论