使用C ++模板匹配类型列表中的类型

时间:2018-09-18 04:42:57

标签: c++ templates variadic-templates

我需要在编译时使用C ++模板匹配类型列表中的类型。这是我的代码,但编译为错误。知道我该如何解决吗?

BoundInputStream

错误是:

template <typename T, typename X, typename... Rs>
struct match
{
    using test = typename std::conditional<std::is_same<T, X>::value, X, bool>::type;
    using more = typename match<T, Rs...>::type;
    using type = typename std::conditional<std::is_same<test, bool>::value, more, test>::type;
};

template <typename T>
struct match<T, bool>
{
    using type = bool;
};

match<int, int, float>::type x;

1 个答案:

答案 0 :(得分:1)

您应该添加部分特殊化以使用恰好两个模板参数来处理这种情况,否则,more的实例化将导致带有一个模板参数的match的实例化,从而发生错误。您的match<T, bool>仅处理最后一个参数为bool的情况,您应将其声明为例如

template <typename T, typename X>
struct match<T, X>
{
    using type = typename std::conditional<std::is_same<T, X>::value, X, bool>::type;
};

此外,我不知道test的用途是什么。我认为直接在more的定义中使用type就足够了:

template <typename T, typename X, typename... Rs>
struct match
{
    using more = typename match<T, Rs...>::type;
    using type = typename std::conditional<std::is_same<T, X>::value, X, more>::type;
};

这仍然不是最佳解决方案,因为即使moreT匹配,也会导致X的实例化(在这种情况下,我们可以断言match::typeX,而没有more的实例化)。为了避免不必要的实例化,您可以添加其他部分专业化:

template <typename T, typename... Rs>
struct match<T, T, Rs...>
{
    using type = T;
};

通过这种部分专业化,主要模板仅与T不是X的情况匹配,因此您可以将主要模板进一步简化为

template <typename T, typename X, typename... Rs>
struct match
{
    using type = typename match<T, Rs...>::type;
};

出于完整性考虑,最终解决方案是:

#include <type_traits>

template <typename T, typename X, typename... Rs>
struct match
{
    using type = typename match<T, Rs...>::type;
};

template <typename T, typename... Rs>
struct match<T, T, Rs...>
{
    using type = T;
};

template <typename T, typename X>
struct match<T, X>
{
    using type = typename std::conditional<std::is_same<T, X>::value, X, bool>::type;
};

static_assert(std::is_same<int, match<int, int, float>::type>::value);