Doc No:N4115

Searching for Types in Parameter Packs

Bill Seymour
Stephan T. Lavavej


This paper proposes that a mechanism for finding types in parameter packs be added to the standard library.

The basic idea:

This paper proposes three new class templates for <type_traits>. One is just a holder of a parameter pack; the other two report at compile time whether a parameter pack contains one or more types.

Possible implementations of the last two are shown as proof of concept. They both compile to either std::true_type or std::false_type.

And in the spirit of N3854, this paper also adds the “_v” values.

A class template that just holds a parameter pack:

    template <class... T> struct packer { };
This is inspired by std::tuple, but it lacks members, so it could serve as an empty base class, and an object of the ultimate type could always be instantiated (even if the parameter pack contains void or some type that lacks a default constructor).

Whether type T is in parameter pack P:

    template <class T, class... P> struct is_contained_in;

    template <class T, class... P>
      constexpr bool is_contained_in_v = is_contained_in<T,P>::value;

One possible implementation:

    template <class T> struct is_contained_in<T> : false_type { };

    template <class First, class... Rest>
      struct is_contained_in<First, First, Rest...> : true_type { };

    template <class T, class First, class... Rest>
      struct is_contained_in<T, First, Rest...>
        : is_contained_in<T, Rest...> { };

Whether a packer, T, has a parameter pack that’s a superset of the pack of some minimum packer, U:

    template <class T, class U> struct contains_types;

    template <class T, class U>
      constexpr bool contains_types_v = contains_types<T,U>::value;

One possible implementation:

    template <class... TPack>
      struct contains_types<packer<TPack...>, packer<>> : true_type { };

    template <class... TPack, class UFirst, class... URest>
      struct contains_types<packer<TPack...>, packer<UFirst, URest...>>
        : integral_constant<bool,
            is_contained_in<UFirst, TPack...>::value &&
            contains_types<packer<TPack...>, packer<URest...>>::value> { };

Standardese relative to N3936:

In 20.10.2 Header <type_traits> synopsis [meta.type.synop]:

In 20.10.3 Helper classes []:

In 20.10.6 Relationships between types [meta.rel], add to the end of Table 51:

template <class T, class... P>
struct is_contained_in;
Type T is contained
in parameter pack P
template <class T, class U>
struct contains_types;
T’s parameter pack contains
at least one instance
of each of the types
in U’s parameter pack
T and U are packers (20.10.3).

Reply to: