How to partially fill in a C++ Template Template Parameter without creating a new class

Viewed 109

Is it possible somehow to "partially" fill in the parameters for a template template parameter, without introducing a new class or using statement for every size?

My code:

#include <vector>
#include <array>
#include <tuple>

struct A { int a = 1; };
struct B { int b = 1; };
struct C { int c = 1; };

template<template<class...> class _Storage, typename... _Components>
struct Foo {
    using Storage = std::tuple<_Storage<_Components>...>;
    Storage storage;

    /* ... do stuff with storage ... */
};

int main() {
    Foo<std::vector,A,B,C> fooV;            // works
    Foo<std::array<...,16>,A,B,C> fooA;     // doesn't work
    return 0;
}

Obviously the "fooA" line above is invalid C++, but it shows my intent.

  • fooV would create my Foo class where the 3 components are stored in std::vectors, so a std::vector<A> for A, a std::vector<B> for B, etc.
  • fooA would create my Foo class where the 3 components are stored in std::array's of max size 16, so a std::array<A, 16> for A, a std::array<B, 16> for B, etc.

The only way I can achieve my intent, is by introducing a templated using statement:

template<typename _T> using MyArray16 = std::array<_T, 16>;

Not it works just fine:

Foo<MyArray16,A,B,C> fooA;      // works

But it's far from optimal that I have to introduce new using types for every array size I need. Ofcourse I can do this easily with #define's and all to avoid code duplication, but it still is far from optimal.

Does anyone know of a syntactical way to achieve this WITHOUT introducing a new class or using statement?

1 Answers

The old rubber duck struck again. Suddenly I found the answer. It still requires a single extra class, but I don't need a new one for every size!

template<size_t N> struct MyArray {
    template<typename _T>
    using Type = std::array<_T, N>;
};

Foo<MyArray<16>::Type,A,B,C> fooA16;        // works!
Foo<MyArray<256>::Type,A,B,C> fooA256;      // works!
Related