有时,我想基于运行时收到的字符串执行一些特定于类型的操作。有一个可以根据字符串向函数模板添加类型的函数会很好。例如,下面的示例应该要求用户输入一种类型,并打印有关该类型的一些信息:
#include <iostream>
#include <type_traits>
#include <typeinfo>
template <typename F, typename ... ArgsT>
auto call_with_type(std::string type, F f, ArgsT... a) {
if (type == "int") {
return f<int>(a...);
} else if (type == "double") {
return f<double>(a...);
} else if (type == "float") {
return f<float>(a...);
}
}
template <typename T>
std::string get_type_name() {
return typeid(T).name();
}
template <typename T>
bool is_integral() {
return std::is_integral<T>::value;
}
int main(int argc, char** argv) {
std::cout << "Enter a data type: ";
std::string type;
std::cin >> type;
std::cout << "Type " << call_with_type(type, get_type_name);
if (call_with_type(type, is_integral)) {
std::cout << " is integral.";
} else {
std::cout << " is not integral.";
}
std::cout << std::endl;
return 0;
}
在这里,call_with_type
函数是重要的部分。它应使用从字符串f
推导出的模板参数来执行函数type
。我知道该程序根本无法完全编译,但是有什么方法可以实现call_with_type
,还是我严重误解了模板的使用方式?
答案 0 :(得分:1)
标签分派可能会有所帮助:
template <typename T> struct Tag{};
template <typename F, typename ... Ts>
auto call_with_type(std::string type, F f, Ts... args) {
if (type == "int") {
return f(Tag<int>{}, args...);
} else if (type == "double") {
return f(Tag<double>{}, args...);
} else if (type == "float") {
return f(Tag<float>{}, args...);
}
}
将通话更改为:
template <typename T>
std::string get_type_name(Tag<T>) {
return typeid(T).name();
}
std::cout << "Type " << call_with_type(type, [](auto tag){ return get_type_name(tag);});