1

I want to use passed template parameter as string. Is it possible?

T is class, what do i need to change to get that code work?

void registerClass(const std::string &name, Handler *handler);

template<class T>
void registerClass() {
   registerClass( "get T as string", new DefaultHandler<T>());
}
5
  • 1
    register is a C++ keyword, you can't use it as an identifier name. Commented Oct 12, 2011 at 19:45
  • yep mistake, sorry. I've edited it, it's not the real code :) Commented Oct 12, 2011 at 19:46
  • 1
    Do you really need the type as a string, or just a different string for each type to use as some kind of dictionary key? Commented Oct 12, 2011 at 19:48
  • I need it as string. Because i'll access it with that class name. Commented Oct 12, 2011 at 19:51
  • 2
    Look at this. Read the answer, it's a good pattern. And if you want demangle the names use abi::__cxa_demangle() (gcc) Commented Oct 12, 2011 at 20:49

4 Answers 4

6

The closest you can get to get a type as a string is with typeid( T )->name(). However, there is no standarization for type names, so you can't trust in getting a valid name from it. A standard compliant implementation may very well return empty strings for all type names.

Sign up to request clarification or add additional context in comments.

3 Comments

typeid is an operator, not a function, so it doesn't live in the std:: namespace. And it returns a pointer so you need to use -> instead of ..
Yes, there's no standartization, it generates names with numbers. So, i'm looking for any other way if possible without declaration of static method inside of each class that i use there.
@MiroK: If you really need the class names, then you are out of luck. The best you could do is provide a function get_type_name and overload it for each of the types you want to support to return the type name.
2

You can use typeid(T) to obtain a std::type_info structure to describe the type. This structure, in turn, has a name() member that should give you the name.

template<class T>
void fooClass() {
   foo( "get " + std::string( typeid(T).name() ) +" as string", new DefaultHandler<T>());
}

2 Comments

You will need a function to clean up the name. For example, GCC prefixes an arbitrary number.
On GCC you can put the typeid through abi::__cxa_demangle() to get a relatively readable type name, but that's not portable.
2

Does it have to be a template parameter? Maybe the C processor can help:

void registerClass(const std::string &name, Handler *handler);

#define REGISTER_CLASS(t) (registerClass( #t, new DefaultHandler<t>()))

void RegisterMyClasses() {  
  REGISTER_CLASS(int);
  REGISTER_CLASS(Foo);
}

Comments

1

C++ doesn't have reflection like C# or Java does. This is not a mistake. Reflection has been considered more than once, and intentionally left out of the language.

HOWEVER, you can get something close to your design. You will have to do a lot of work yourself. You will have to, essentially, implement reflection in a language that intentionally doesn't provide it.

Your current design is close. If I were to implement reflection the way you appear to be going I would do:

class Reflection_registry {
    std::map<std::string, Handler*> registry_;

public:
    void registerClass(const std::string& name, Handler* handler) {
        registry_[name] = handler;
    }

    Handler* getHandlerForClass(std::string& name) {
        std::map<std::string, Handler*>::iterator itor = registry_.find(name);
        return itor == registry_.end() ? NULL : itor->second;
    }
}

The thing is that you will be responsible for coming up with the relevant names, by hand, and keeping them up to date. As others have suggested, you can use typeid and std::type_infos to generate the names -- that's pretty much the kind of thing std::type_info was designed for.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.