可以使用模板参数作为字符串吗?

时间:2011-10-12 19:43:36

标签: c++ templates

我想使用传递的模板参数作为字符串。有可能吗?

T是类,我需要更改什么来使代码工作?

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

template<class T>
void registerClass() {
   registerClass( "get T as string", new DefaultHandler<T>());
}

4 个答案:

答案 0 :(得分:6)

您可以使用typeid( T )->name()获得最接近字符串类型的字符。但是,类型名称没有标准化,因此您无法信任从中获取有效名称。标准兼容的实现很可能返回所有类型名称的空字符串。

答案 1 :(得分:2)

您可以使用typeid(T)获取std::type_info结构来描述类型。反过来,这个结构有一个name()成员,可以给你起名字。

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

答案 2 :(得分:2)

是否必须是模板参数?也许C处理器可以提供帮助:

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

答案 3 :(得分:1)

C ++没有像C#或Java那样的reflection。这不是一个错误。反思被不止一次考虑过,故意被排除在语言之外。

可以获得贴近您设计的内容。你自己必须做很多工作。实际上,您必须使用有意提供它的语言来实现反射。

您当前的设计很接近。如果我按照你的方式实现反思,我会这样做:

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

问题在于将负责提供相关名称,手动,并使其保持最新状态。正如其他人所建议的那样,您可以使用typeidstd::type_info来生成名称 - 这几乎就是std::type_info的设计目标。