C++ 可以将模板参数用作字符串吗?
我想使用传递的模板参数作为字符串。可能吗 T是类,我需要更改什么才能使代码正常工作C++ 可以将模板参数用作字符串吗?,c++,templates,C++,Templates,我想使用传递的模板参数作为字符串。可能吗 T是类,我需要更改什么才能使代码正常工作 void registerClass(const std::string &name, Handler *handler); template<class T> void registerClass() { registerClass( "get T as string", new DefaultHandler<T>()); } void注册表类(const std::s
void registerClass(const std::string &name, Handler *handler);
template<class T>
void registerClass() {
registerClass( "get T as string", new DefaultHandler<T>());
}
void注册表类(const std::string和name,Handler*Handler);
模板
无效注册表类(){
registerClass(“获取T作为字符串”,new DefaultHandler());
}
您可以使用typeid(T)
获得描述类型的std::type\u info
结构。此结构又有一个name()
成员,该成员应为您提供名称
template<class T>
void fooClass() {
foo( "get " + std::string( typeid(T).name() ) +" as string", new DefaultHandler<T>());
}
模板
void类(){
foo(“get”+std::string(typeid(T).name())+“as string”,new DefaultHandler());
}
您可以使用typeid(T)
获得描述类型的std::type\u info
结构。此结构又有一个name()
成员,该成员应为您提供名称
template<class T>
void fooClass() {
foo( "get " + std::string( typeid(T).name() ) +" as string", new DefaultHandler<T>());
}
模板
void类(){
foo(“get”+std::string(typeid(T).name())+“as string”,new DefaultHandler());
}
最接近字符串形式的类型是typeid(T)->name()
。但是,类型名没有标准化,因此您不能信任从中获取有效的名称。符合标准的实现很可能会为所有类型名返回空字符串。最接近字符串类型的方法是使用typeid(T)->name()。但是,类型名没有标准化,因此您不能信任从中获取有效的名称。符合标准的实现很可能会为所有类型名返回空字符串。C++不像C#或Java那样有空字符串。这不是一个错误。反思已经被考虑了不止一次,并且被有意地排除在语言之外
然而,你可以得到与你的设计相近的东西。你将不得不自己做很多工作。本质上,您必须用一种故意不提供反射的语言来实现反射
您当前的设计非常接近。如果我按照您的方式实施反射,我会:
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;
}
}
类反射\u注册表{
地图注册;
公众:
无效注册表类(const std::string&name,Handler*Handler){
注册表\[name]=处理程序;
}
Handler*getHandlerForClass(标准::字符串和名称){
std::map::迭代器itor=registry\uux.find(名称);
return-itor==registry.end()?NULL:itor->second;
}
}
问题是,您将负责手工提供相关的名称,并使其保持最新。正如其他人所建议的那样,您可以使用typeid
和s来生成名称——这与std::type_info
的设计目的差不多。C++不像C++或Java那样。这不是一个错误。反思已经被考虑了不止一次,并且被有意地排除在语言之外
然而,你可以得到与你的设计相近的东西。你将不得不自己做很多工作。本质上,您必须用一种故意不提供反射的语言来实现反射
您当前的设计非常接近。如果我按照您的方式实施反射,我会:
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;
}
}
类反射\u注册表{
地图注册;
公众:
无效注册表类(const std::string&name,Handler*Handler){
注册表\[name]=处理程序;
}
Handler*getHandlerForClass(标准::字符串和名称){
std::map::迭代器itor=registry\uux.find(名称);
return-itor==registry.end()?NULL:itor->second;
}
}
问题是,您将负责手工提供相关的名称,并使其保持最新。正如其他人所建议的,您可以使用typeid
和s来生成名称——这与std::type_info
的设计目的差不多。它必须是模板参数吗?也许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);
}
void注册表类(const std::string和name,Handler*Handler);
#定义寄存器类(t)(寄存器类(#t,新的DefaultHandler())
void registerMyClass(){
注册类别(int);
注册课程(Foo);
}
它必须是模板参数吗?也许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);
}
void注册表类(const std::string和name,Handler*Handler);
#定义寄存器类(t)(寄存器类(#t,新的DefaultHandler())
void registerMyClass(){
注册类别(int);
注册课程(Foo);
}
<代码>代码>登记器< /Cord>是C++关键字,不能用它作为标识符。我已经编辑了它,它不是真正的代码:)您真的需要将类型作为字符串,还是每个类型使用不同的字符串作为某种字典键?我需要它作为字符串。因为我将使用该类名访问它。请看。阅读答案,这是一个很好的模式。如果你想让名字被混淆,使用<代码> ABI::YXCXAYDEMAGLYLE()/Cux>(GCC)<代码>登记器< /Cord>是C++关键字,不能用它作为标识符。我已经编辑了它,它不是真正的代码:)您真的需要将类型作为字符串,还是每个类型使用不同的字符串作为某种字典键?我需要它作为字符串。因为我将使用该类名访问它。请看。阅读答案,这是一个很好的模式。如果需要demangle,则名称使用abi::\uucxa\uDemangle()
(gcc)typeid
是一个运算符,而不是一个函数,因此它不存在于std:
命名空间中。它返回一个指针,因此您需要使用->
而不是
。是的,没有标准化,它生成带有数字的名称。所以,如果可能的话,我正在寻找其他方法,而不在我使用的每个类中声明静态方法。@MiroK:如果你真的需要类名,那你就走运了