c++c++11templatesmetaprogrammingvariadic

Check if parameter pack contains a type


I was wondering if C++0x provides any built-in capabilities to check if a parameter pack of a variadic template contains a specific type. Today, boost:::mpl::contains can be used to accomplish this if you are using boost::mpl::vector as a substitute for variadic templates proper. However, it has serious compilation-time overhead. I suppose, C++0x has compiler-level support for std::is_same. So I was thinking if a generalization like below is also supported in the compiler.

template <typename... Args, typename What>
struct is_present
{
  enum { value = (What in Args...)? 1 : 0 };
};

Solution

  • No, you have to use (partial) specialization with variadic templates to do compile-time computations like this:

    #include <type_traits>
    
    template < typename Tp, typename... List >
    struct contains : std::true_type {};
    
    template < typename Tp, typename Head, typename... Rest >
    struct contains<Tp, Head, Rest...>
    : std::conditional< std::is_same<Tp, Head>::value,
        std::true_type,
        contains<Tp, Rest...>
    >::type {};
    
    template < typename Tp >
    struct contains<Tp> : std::false_type {};
    

    There is only one other intrinsic operation for variadic templates and that is the special form of the sizeof operator which computes the length of the parameter list e.g.:

    template < typename... Types >
    struct typelist_len
    {
       const static size_t value = sizeof...(Types);
    };
    

    Where are you getting "it has serious compilation-time overhead" with boost mpl from? I hope you are not just making assumptions here. Boost mpl uses techniques such as lazy template instantiation to try and reduce compile-times instead of exploding like naive template meta-programming does.