考虑以下示例:
#include <iostream>
#include <type_traits>
template <typename Type>
struct Something
{
template <typename OtherType>
static constexpr bool same()
{return std::is_same<Type, OtherType>::value;}
};
template <class Type>
struct Example
{
static_assert(Type::template same<double>(), "ERROR");
};
int main()
{
Example<Something<double>> example;
return 0;
}
static_assert
通过执行same()
函数检查传递的类型是否满足某些条件。
现在考虑可以将多个Types
传递给Example
:
#include <iostream>
#include <type_traits>
template <typename Type>
struct Something
{
template <typename OtherType>
static constexpr bool same()
{return std::is_same<Type, OtherType>::value;}
};
template <class... Types>
struct Example
{
static_assert(/* SOMETHING */, "ERROR");
};
int main()
{
Example<Something<double>> example;
return 0;
}
是否有一个工作语法而不是SOMETHING
来检查条件是否在所有类型上得到验证(没有一堆辅助函数:我知道可以这样做但我不知道是否有另一种方式(比如在某处使用简单的拆包......)
答案 0 :(得分:1)
您可以使用参数包唯一可以将其作为一组参数解压缩到函数中。所以不,没有助手就不能这样做。
如果您允许辅助功能,则有一千种方法可以执行此操作。最明显的是某种logical_and
template<class first, class ...rest>
constexpr bool logical_and(first f, rest... r)
{return bool(f) && logical_and(std::forward<rest>(r)...));}
// ^unpack the rest recursively^
template<class last>
constexpr bool logical_and(last l)
{return bool(l);}
template <class... Types>
struct Example
{
static_assert(logical_and(Something<double>::same<Types>()...), "ERROR");
// ^unpack the results to the function^
};
这是完全未经测试的,可能不会按原样编译
答案 1 :(得分:0)
只需专门化即可完成辅助功能
template Example
。
如果在现实世界中Example
是你的一个班级
不想仅仅为了变量而专攻
static_assert
然后您可以封装可变参数static_assert
在自己的模板专业化和你的真实世界类
继承相应的实例化。这是一个例子
只是专门化Example
:
#include <iostream>
#include <type_traits>
template <typename Type>
struct Something
{
template <typename OtherType>
static constexpr bool same()
{return std::is_same<Type, OtherType>::value;}
};
template<class ...Types>
struct Example;
template<>
struct Example<>{};
template<class T>
struct Example<T>
{
static_assert(T::template same<double>(), "ERROR");
};
template<class First, class ...Rest>
struct Example<First,Rest...> : Example<Rest...>
{
static_assert(First::template same<double>(), "ERROR");
};
int main()
{
Example<Something<double>> example0; // OK
Example<Something<double>,Something<double>> example1; // OK
Example<Something<int>> example2; // Error
Example<Something<double>,Something<int>> example3; // Error
Example<Something<double>,Something<double>,Something<int>> example4; // Error
Example<Something<double>,Something<int>,Something<double>> example5; // Error
return 0;
}