我想使用传递的模板参数作为字符串。有可能吗?
T是类,我需要更改什么来使代码工作?
void registerClass(const std::string &name, Handler *handler);
template<class T>
void registerClass() {
registerClass( "get T as string", new DefaultHandler<T>());
}
答案 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;
}
}
问题在于你将负责提供相关名称,手动,并使其保持最新状态。正如其他人所建议的那样,您可以使用typeid
和std::type_info
来生成名称 - 这几乎就是std::type_info
的设计目标。