kravemir
kravemir

Reputation: 10986

Is possible to use template argument as string?

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>());
}

Upvotes: 1

Views: 1465

Answers (4)

Max Lybbert
Max Lybbert

Reputation: 20031

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.

Upvotes: 1

Robᵩ
Robᵩ

Reputation: 168616

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);
}

Upvotes: 2

K-ballo
K-ballo

Reputation: 81349

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.

Upvotes: 6

Alexander Gessler
Alexander Gessler

Reputation: 46607

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>());
}

Upvotes: 2

Related Questions