0

I am trying to find a way to specialize a template class in such a way that it can also handle template template (and template template template ...) parameters. Below is a simple code that demonstrates what I am trying to do. Since Foo expect a type as its template parameters, passing it a std::pair or std::vector causes compilation error. My impression is that in C++11/14/17 this is not natively supported. If this is really the case, and design recommendations are also more than welcome.

Thanks!

#include <utility>

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

int main()
{
    using Type1 = Foo<int> ;
    using Type2 = Foo<std::pair<int, char>>;
    // using Type3 = Foo<int, char, std::pair>; // => does not compile
                                                // error : expected a type, got 'pair'
}
ozlsn
  • 144
  • 4
  • 4
    How would you intend to use `Type3`? – Cory Kramer May 18 '20 at 19:49
  • 2
    C++ does not offer a way to mix variadic type, non-type and template-template parameters. What exactly is your use case for this? – NathanOliver May 18 '20 at 19:57
  • Depending on what you actually want to accomplish, use might want to take a look at allocators [rebinding](https://stackoverflow.com/q/12362363) that is used in the standard library. – Evg May 18 '20 at 19:59

1 Answers1

0

std::pair is not a regular type, it's type that accepts two template params (and std::vector accepts a single template param). To pass it as a template type argument, you can use template of template:

template<template<class...> typename ContainerT, typename ...>
struct Foo{};

This way the following code will compile:

int main()
{
    // using Type1 = Foo<int> ; // Won't compile
    // using Type2 = Foo<std::pair<int, char>>; // Won't compile
    using Type3 = Foo<std::pair, int, char>;
}

Otherwise, there was no need of template<template...> usage, you could always use just template<...>.

Coral Kashri
  • 3,436
  • 2
  • 10
  • 22