我需要在编译时使用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;
答案 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;
};
这仍然不是最佳解决方案,因为即使more
与T
匹配,也会导致X
的实例化(在这种情况下,我们可以断言match::type
为X
,而没有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);