[英]Check for arguments type in a variadic template declaration
I got a plain variadic template declaration, just like the classic one:我得到了一个普通的可变参数模板声明,就像经典的一样:
template <typename... Arguments>
class VariadicTemplate;
What I need to achieve is in by letting the VariadicTemplate
class do perform some type checking;我需要实现的是让
VariadicTemplate
类执行一些类型检查; the variadic template should check in some iterative form that all the arguments received should be let say of the type <Foo>
.可变参数模板应该以某种迭代形式检查接收到的所有参数都应该是
<Foo>
类型。
I have seen something similar somewhere but now I can not recognize where it was :P我在某处看到过类似的东西,但现在我不知道它在哪里:P
struct Foo {};
#include <type_traits>
template<class T, class...>
struct are_same : std::true_type
{};
template<class T, class U, class... TT>
struct are_same<T, U, TT...>
: std::integral_constant<bool, std::is_same<T,U>{} && are_same<T, TT...>{}>
{};
template<typename... Arguments>
class VariadicTemplate
{
static_assert(are_same<Foo, Arguments...>{}, "a meaningful error message");
};
int main()
{
VariadicTemplate<Foo, Foo, Foo, Foo> v0{}; (void)v0;
VariadicTemplate<Foo, int, Foo, double> v1{}; (void)v1;
}
But something tells me you want to know if the arguments are all specializations of a class template Foo
:但是有些事情告诉我你想知道参数是否都是类模板
Foo
:
template<class T, class U>
struct Foo {};
#include <type_traits>
template<template<class...> class T, class U>
struct is_template_of
{
template<class... TT>
static std::true_type test(T<TT...>*);
static std::false_type test(...);
constexpr static bool value = decltype(test((U*)nullptr)){};
};
template<template<class...> class T, class...>
struct is_template_of_N : std::true_type
{};
template<template<class...> class T, class U, class... TT>
struct is_template_of_N<T, U, TT...>
: std::integral_constant<bool, is_template_of<T,U>::value
&& is_template_of_N<T, TT...>{}>
{};
template<typename... Arguments>
class VariadicTemplate
{
static_assert(is_template_of_N<Foo, Arguments...>{},
"a meaningful error message");
};
int main()
{
VariadicTemplate<Foo<int, double>, Foo<int, int>> v0; (void)v0;
VariadicTemplate<Foo<int, double>, int> v1; (void)v1;
}
Here there is anothe solution :P这里有另一个解决方案:P
Here it is:这是:
template <bool... b> struct static_all_of;
// do recursion if the first argument is true
template <bool... tail>
struct static_all_of<true, tail...> : static_all_of<tail...> {};
// end recursion if first argument is false
template <bool... tail>
struct static_all_of<false, tail...> : std::false_type {};
// end recursion if no more arguments need to be processed
template <> struct static_all_of<> : std::true_type {};
// First template argument is given as the type checking for the is_base_of() function
template <typename Type, typename... Requirements>
class CollectionOfCommonBase : public Requirements...
{
static_assert(static_all_of<std::is_base_of<Type, Requirements>::value...>::value, "One or more template arguments are not base_of the one specified - given template specialization is not allowed.");
};
So you got it working for:所以你让它工作:
class Foo {};
class AFoo : public Foo {};
class BFoo : public Foo {};
class MyCollection : public CollectionOfCommonBase<Foo, AFoo, BFoo> {};
If you want to check the types (not inquiring about base types):如果要检查类型(不询问基本类型):
#include <type_traits>
template <typename ...>
struct are_same : std::true_type {};
template <typename S, typename T, typename ... Ts>
struct are_same <S, T, Ts...> : std::false_type {};
template <typename T, typename ... Ts>
struct are_same <T, T, Ts...> : are_same<T, Ts...> {};
template <typename ... Ts>
inline constexpr bool are_same_v = are_same<Ts...>::value;
Handling your example problem:处理您的示例问题:
template <typename ... Foos>
void Foo (Foos ... foos)
{
static_assert(are_same_v<int, Foos...>);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.