Jump to content
  • Advertisement
Sign in to follow this  
vbuser1338

Retrieving name of c++ type

This topic is 4074 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm working on my scripting system and I want to know if there is a way to get the class name of a template parameter. Right now you explicitly pass the name of the class and I am wondering if there is a portable way of getting the class name. I tried typeid but it includes other stuff with the class name (for example I get "4Test" instead of Test). I looked through boost but didn't find anything. Here is how I have it now:
// Push an object to the function
template <typename T>
template <typename ObjectType>
void Function<T>::pushArgument(const std::string &objectTypename, ObjectType argument) {
     arguments.push_back(ArgumentPtr(new ObjectArgument<ObjectType>(objectTypename, argument)));
}

// Class wrapping the passing of an object to lua
template <typename T>
class ObjectArgument : public FunctionArgument {
     private:
          const std::string objectTypename;   // The class name of this type
          T argumentValue;
     public:
          ObjectArgument(const std::string &objectTypename_, T &argumentValue_) : objectTypename(objectTypename_), argumentValue(argumentValue_)  {}
          virtual void push(lua_State *luaState);
};

template <typename T>
inline void ObjectArgument<T>::push(lua_State *luaState) {
     assert(luaState && "No created lua state to push argument");
     tolua_pushusertype(luaState, &argumentValue, objectTypename.c_str());
}

// Example usage
class Test { ... };
Utils::Scripting::Function<Test> objectFunction(lua, "test.lua", "objectFunction");
objectFunction.pushArgument("Test", Test(20));
Test test = objectFunction();
test.print();

Is there a easy way to just go objectFunction.pushArgument(Test(20)) and able to get the class name? Thanks for any help

Share this post


Link to post
Share on other sites
Advertisement
In theory, you can use the typeid operator to get a std::type_info structure that describes a type. type_info then has a name() member function that returns a human readable string for the name of the type. However, the result of type_info::name() will be different from compiler to compiler.

Share this post


Link to post
Share on other sites
Quote:
and I am wondering if there is a portable way of getting the class name


No.

Name mangling is compiler specific, in case of MVC proprietary and subject to change.


The only portable and reliable way is to define types yourself.

This may seem somewhat strange, but type names depend on the library the executable was compiled with as well. std::wstring on MVC will be different than the one compiled under gcc. Not only in some minor implementation, but it'll be a completely different class (sort of like int on one platform, char on another).

Share this post


Link to post
Share on other sites
Thanks, thats what I tried but as you said it varies from compilers so I cannot just remove the "4" from "4Test" to get the class name. I guess I will have to continue explicitly passing the class name.

Share this post


Link to post
Share on other sites
You could always do something like this:
stdext::hash_map<std::type_info, std::string> TypeNames;

Every time you created a new type, you'd have to insert an entry into the map for it, but then you could just get the type's name by looking up it's type_info in the map. *shrug*

Share this post


Link to post
Share on other sites
Quote:
Original post by Driv3MeFar
You could always do something like this:
stdext::hash_map<std::type_info, std::string> TypeNames;

Every time you created a new type, you'd have to insert an entry into the table for it, but then you could just get the type's name by looking up it's type_info in the map. *shrug*


Or use Loki typelists, and use that to do compile time resolution of type into index and vice-versa.

Share this post


Link to post
Share on other sites
This is a possibility and probably is safer then typing the class name every time I call a function with that type and possibly mistyping it. Thanks for the suggestion.

Share this post


Link to post
Share on other sites
type_info can't be used in a (hash)map. It's non-constructible. You have to use a proxy object, which is something of a pain.

Share this post


Link to post
Share on other sites
Quote:
Original post by SiCrane
type_info can't be used in a (hash)map. It's non-constructible. You have to use a proxy object, which is something of a pain.


Oh, didn't know that. I guess you could do the same thing and just map the mangled name to a readable one, so:

stdext::hash_map<std::string, std::string> TypeNames;

class A
{
...
};

A a;
TypeNames.insert( typeid(a).name(), "A" );

Share this post


Link to post
Share on other sites
type_info::name() also isn't guaranteed to return a unique name. For example if you have NamespaceA::cow and NamespaceB::cow, name() might be "cow" for both of them. In general, for the proxy object your need to store pointers the type_info objects that typeid returns. As I mentioned, it's something of a pain.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!