Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
527 views
in Technique[技术] by (71.8m points)

c++ - 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; the variadic template should check in some iterative form that all the arguments received should be let say of the type <Foo>.

I have seen something similar somewhere but now I can not recognize where it was :P

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
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:

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;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...