Если честно, я не уверен в понимании вашего вопроса. Насколько я понимаю, я считаю, что вам не нужен своего рода диспетчер во время выполнения, чтобы вычислить строку, содержащую имя типа. Просто вы пишете общую функцию шаблона, которая вызывает специальную оболочку шаблона, которая устраняет неоднозначность вызова 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()
не будет такой похожей.