C++ 将字符串转换为类型名
C++ convert string to typename
所以我发现了很多文章和帖子都说无法将 typename
转换为 string
但我还没有找到相反的方法。我有一个 template
的函数,具有特殊化:
template <typename T>
void foo(T sth) {}
template <>
void foo<int>(int sth) {}
...
我正在读取这样构造的文件:
int 20
double 12.492
string word
有没有办法根据文件内容调用foo()
的正确特化?
是的,但它需要手动代码,并且您知道将出现在文件中的所有类型。那是因为模板是编译时构造的,它们不能在运行时实例化。
如果需要,您始终可以使用预处理器或其他技巧来尝试减少样板文件。
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));
}
当然,这需要你传入正确的类型(没有隐式转换!)。我看不出有什么办法可以避免这种情况。
老实说,我不确定是否理解你的问题。正如我所解释的那样,我相信您在 运行 时间内不需要一种调度程序来计算包含类型名称的字符串。只需编写一个通用模板函数,调用一个特殊的模板包装器,根据类型消除对 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()
的每个专业版本都不会如此相似。
所以我发现了很多文章和帖子都说无法将 typename
转换为 string
但我还没有找到相反的方法。我有一个 template
的函数,具有特殊化:
template <typename T>
void foo(T sth) {}
template <>
void foo<int>(int sth) {}
...
我正在读取这样构造的文件:
int 20
double 12.492
string word
有没有办法根据文件内容调用foo()
的正确特化?
是的,但它需要手动代码,并且您知道将出现在文件中的所有类型。那是因为模板是编译时构造的,它们不能在运行时实例化。
如果需要,您始终可以使用预处理器或其他技巧来尝试减少样板文件。
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));
}
当然,这需要你传入正确的类型(没有隐式转换!)。我看不出有什么办法可以避免这种情况。
老实说,我不确定是否理解你的问题。正如我所解释的那样,我相信您在 运行 时间内不需要一种调度程序来计算包含类型名称的字符串。只需编写一个通用模板函数,调用一个特殊的模板包装器,根据类型消除对 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()
的每个专业版本都不会如此相似。