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() 的每个专业版本都不会如此相似。