我正在尝试实现一个基本模板元编程结构,它使用std::is_same
确定类型列表是否完全相同。我尝试按如下方式实现它:
template <typename T, typename U, typename... Args>
struct check_same {
static const bool value = std::is_same<T, U>::value && check_same<U, Args...>::value;
};
template <typename T, typename U>
struct check_same {
static const bool value = std::is_same<T, U>::value;
};
但是,如果我尝试实例化check_same
,我会收到以下编译器错误:
&#39; check_same&#39; :模板参数太少
为什么这不是执行编译时布尔代数的有效方法?当然所涉及的所有表达式都是constexpr
(或const
,因为MSVC还没有实现constexpr
),它应该编译吗?
以下将无法编译:
int main()
{
static_assert( check_same<int, unsigned int, float>::value, "Types must be the same" );
return 0;
}
答案 0 :(得分:4)
C ++中的类模板不能超载&#34;喜欢的功能。您不能使用不同的参数集一次又一次地重新声明相同的模板,并期望它能够编译。例如,这不会编译
template <typename A> struct S {};
template <typename A, typename B> struct S {};
它不会编译,因为它试图两次声明模板类S
。这是非法的。
您的代码遇到完全相同的错误:您已经声明了模板check_same
两次。你不能这样做。
您显然尝试使用的技术应基于模板专业化,而不是基于模板重新声明。您只需要声明一次主要模板
template <typename T, typename U, typename... Args>
struct check_same {
static const bool value = std::is_same<T, U>::value && check_same<U, Args...>::value;
};
然后为特定的,更受限制的参数集提供该主要模板的部分特化
template <typename T, typename U>
struct check_same<T, U> {
static const bool value = std::is_same<T, U>::value;
};
答案 1 :(得分:2)
试试这个:
template <typename T, typename... Args>
struct check_same: std::true_type {};
template <typename T, typename U, typename...Args>
struct check_same<T,U,Args...>: std::integral_constant<bool,
std::is_same<T,U>::value && check_same<U, Args...>::value
> {};
第一个只在只有一个参数的情况下进行评估。第二个专业化获得2个或更多。
如果传递0个参数,则会出错。我认为你也应该处理这个问题:
template <typename... Args>
struct check_same: std::true_type {};
template <typename T, typename U, typename...Args>
struct check_same<T,U,Args...>: std::integral_constant<bool,
std::is_same<T,U>::value && check_same<U, Args...>::value
> {};
实际上不需要专门化,因为第一个适用于0和1参数。