简体   繁体   中英

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

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.

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

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

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_info s to generate the names -- that's pretty much the kind of thing std::type_info was designed for.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM