我需要在编译时使用C ++模板匹配类型列表中的类型。这是我的代码,但它编译成错误。知道我怎么解决它?
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.cpp:99:45: error: wrong number of template arguments (1, should be at least 2)
using more = typename match<T, Rs...>::type;
^
您应该添加一个部分特化来处理具有两个模板参数的情况,否则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);