Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if all of variadic template arguments have special function?

Explanation:

Checking if a special operator exist in a template parameter is easy (with help of this answer).

The following code checks if char operator[] exists in Type or not:

template <class Type>
class HasStringOperator
{
    template <typename T, T> struct TypeCheck;

    typedef char Yes;
    typedef long No;
    template <typename T> struct operator_{
        typedef char (T::*fptr)(int);
    };

    template <typename T> static Yes HasOperator(TypeCheck< typename operator_<T>::fptr, &T::operator[] >*);
    template <typename T> static No  HasOperator(...);

public:
    static bool const value = (sizeof(HasOperator<Type>(0)) == sizeof(Yes));
};

ideone

Problem:

Now I want to check if all of my variadic template parameters have that operator. I can't figure out how to send them one by one to HasStringOperator and check the whole result.

template < class... Word>
class Sentence
{
    static_assert(Do all of Words have 'char operator[]'?);
};

What should I do?

like image 928
uchar Avatar asked Jun 08 '14 17:06

uchar


People also ask

What is a variadic template c++?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.

Can we pass Nontype parameters to templates?

Template non-type arguments in C++It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

How do you call a variadic function?

You don't have to do anything special to call a variadic function. Just put the arguments (required arguments, followed by optional ones) inside parentheses, separated by commas, as usual. But you must declare the function with a prototype and know how the argument values are converted.


1 Answers

Just apply it to every type and compare it to an array of trues.

template <bool... b>
struct BoolArray {};

template <class... TS>
struct DenyType : true_type {};

template <class... World>
class Sentence {
    static_assert(is_same<
        BoolArray<(HasStringOperator<World>::value)...>,
        BoolArray<(DenyType<World>::value)...>
    >::value, "WUT");
};
like image 89
polkovnikov.ph Avatar answered Oct 13 '22 23:10

polkovnikov.ph