根据运行时提供的类型执行模板功能

时间:2019-08-29 21:22:04

标签: c++ templates

有时,我想基于运行时收到的字符串执行一些特定于类型的操作。有一个可以根据字符串向函数模板添加类型的函数会很好。例如,下面的示例应该要求用户输入一种类型,并打印有关该类型的一些信息:

#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,还是我严重误解了模板的使用方式?

1 个答案:

答案 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);});