开发者

Is possible to use template argument as string?

开发者 https://www.devze.com 2023-04-12 09:47 出处:网络
I want to use passed template pa开发者_C百科rameter as string. Is it possible? T is class, what do i need to change to get that code work?

I want to use passed template pa开发者_C百科rameter 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_infos to generate the names -- that's pretty much the kind of thing std::type_info was designed for.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号