根据模板参数选择功能名称

时间:2014-04-02 14:00:21

标签: c++ templates generic-programming

有没有办法根据模板参数在多个非模板函数之间自动选择?

示例:

class Aggregate
{
public:
     std::string asString();
     uint32_t asInt();
private:
     // some conglomerate data
};

template <typename T>
T get(Aggregate& aggregate)
{
     // possible map between types and functions?
     return bind(aggregate, typeConvert[T])(); ??
     // or
     return aggregate.APPROPRIATE_TYPE_CONVERSION();
}

如果没有可用的良好转换,那么解决方案很可能会抛出编译错误,即

get<double>(aggregate); // compile error

我不想使用模板专业化,即

template<>
int get(Aggregate& aggregate)
{
    return aggregate.asInt();
}

因为当你的get()函数有多行代码

时会导致代码重复

2 个答案:

答案 0 :(得分:2)

行人路是分别定义每个可能的选项:

template <typename T> T get(Aggregate &);    // leave undefined

template <> uint32_t get(Aggregate & a) { return a.asInt(); }

// ...

如果没有任何更系统的结构来编码哪个功能可以进行哪种转换,我认为这是你能做的最好的。但是,重新定义Aggregate可能值得更加内省。

答案 1 :(得分:1)

您可以执行类似(要求C ++ 11):( https://ideone.com/UXrQFm

template <typename T, typename... Ts> struct get_index;

template <typename T, typename... Ts>
struct get_index<T, T, Ts...> : std::integral_constant<std::size_t, 0> {};

template <typename T, typename Tail, typename... Ts>
struct get_index<T, Tail, Ts...> :
    std::integral_constant<std::size_t, 1 + get_index<T, Ts...>::value> {};

template <typename T, typename Tuple> struct get_index_in_tuple;

template <typename T, typename ... Ts>
struct get_index_in_tuple<T, std::tuple<Ts...>> : get_index<T, Ts...> {};


class Aggregate
{
public:
     std::string asString();
     uint32_t asInt();
private:
     // some conglomerate data
};

template <typename T>
T get(Aggregate& aggregate)
{
    using types = std::tuple<uint32_t, std::string>;
    auto funcs = std::make_tuple(&Aggregate::asInt, &Aggregate::asString);

    return (aggregate.* (std::get<get_index_in_tuple<T, types>::value>(funcs)))();
}