Search code examples
c++templatesvariadic-templatesvariadic-functionsvariadic

How to check if a type is instantiated from a certain variadic template class in a template function?


Let's say I have:

template <typename...>
class Foo { };

Then I define another function:

template <typename... T>
void Bar(const T&... arguments) { }

How do I check if all Ts passed to Bar are all instantiated from Foo? Like:

Foo<int> a;
Foo<int, int> b;
Bar(a, b); // OK
int c;
Bar(a, b, c); // ill-formed

I want a way to detect ill-formed arguments like Bar(a, b, c); Is there a way to do this?


Solution

  • You can create a trait to test for instantiations of Foo, and then fold it across all your parameters.

    template <typename>
    struct is_foo : std::false_type {};
    
    template <typename... Ts>
    struct is_foo<Foo<Ts...>> : std::true_type {};
    
    template <typename T>
    constexpr bool is_foo_v = is_foo<T>::value;
    
    template <typename... T>
    void Bar(const T&... arguments) {
        static_assert((is_foo_v<T> && ...), "arguments must all be Foos");
    }
    

    See it on coliru