因此,我找到了许多文章和帖子,说没有办法将typename
转换为string
,但是我没有找到相反的方法。我有一个template
的函数,具有专门化的功能:
template <typename T>
void foo(T sth) {}
template <>
void foo<int>(int sth) {}
...
我正在从一个像这样构造的文件中读取内容:
int 20
double 12.492
string word
是否有一种方法可以根据文件的内容来调用foo()
的正确专业化?
答案 0 :(得分:3)
是的,但是需要手动代码,并且您知道文件中将出现的所有类型。这是因为模板是编译时构造,因此无法在运行时实例化。
如果愿意,您总是可以使用预处理器或其他技巧来减少样板。
void callFoo(std::string type, std::any arg) {
if (type == "int")
foo<int>(std::any_cast<int>(arg));
else if (type == "double")
foo<double>(std::any_cast<double>(arg));
else if (type == "string")
foo<std::string>(std::any_cast<std::string>(arg));
}
当然,这要求您传递正确的类型(没有隐式转换!)。我看不出有什么办法可以避免这种情况。
答案 1 :(得分:0)
说实话,我不确定要了解您的问题。按照我的解释,我相信您不需要在运行时就需要一种调度程序来计算包含类型名称的字符串。只需编写一个通用模板函数即可,该函数调用一个特殊的模板包装器,该包装器根据类型消除对foo()
的调用。您要求专门的foo()
接收另一个用于消除歧义的特殊参数(the_type<T>
)。
这里是完整且可运行的演示:
# include <string>
# include <iostream>
using namespace std;
template<class T> struct the_type { using type = T; };
template <typename T>
void foo(const T par)
{
foo(par, the_type<T>());
}
void foo(int par, the_type<int>)
{
cout << "int " << par << endl;
}
void foo(double par, the_type<double>)
{
cout << "double " << par << endl;
}
void foo(const string & par, the_type<string>)
{
cout << "string " << par << endl;
}
void foo(const char * par, the_type<const char*>)
{
cout << "char* " << par << endl;
}
int main()
{
foo(20);
foo(12.492);
foo("word");
foo(string("word"));
}
其输出是:
int 20
double 12.492
char* word
string word
如果您需要另一种专业化,则只需对其进行定义。在某些情况下,您将必须明确地将专业化定义为模板参数。
您可以使用宏操作来避免重复操作。例如,假设foo()
结构相同,则可以将其封装在宏中。像这样:
# define GENFOO(type_name) \
void foo(type_name par, the_type<type_name>) \
{ \
cout << #type_name " " << par << endl; \
}
GENFOO(int);
GENFOO(double);
GENFOO(string)
但是,我想说foo()
的每个专业版本都不会如此相似。