Question: I have a base class and a class template, and I want to be able to instantiate it as follows:

```
class Base
{
};

template<int i>
class Foo
{
};

namespace SomeEnum
{
enum
{
    First,
    Second,
    Third,
    ...
    Last
};
}

void bar()
{
    std::unique_ptr<Base> ptr{ nullptr };
    int fooType = rand() % SomeEnum::Last;

    ptr = std::make_unique<Foo<fooType>> // Causes error because I'm passing a run-time value to something that expects a compile-time value
}

```

The enum used to be a class enum but I changed it to a regular enum so that I could use the design presented above, since the enum in question is quite large. I thought I was being clever at the time but I now realize I had kind of forgotten that templates are handled at compile-time.

Is there any way to circumvent this, without completely changing my design? I could obviously do something like this:

```
switch(fooType)
{
case 0:
    ptr = std::make_unique<Foo<0>>();
    break;
case 1:
    ptr = std::make_unique<Foo<1>>();
    break;
...
}

```

But it doesn't look very elegant and pretty much removes the motivation for not just using a class enum since I will have to make a switch case for every value in the enum. Is there any other solution, or have I painted myself into a corner with this design?

Answer: 
A simple solution would be this:

```
namespace detail {
    template<size_t I>
    std::unique_ptr<Base> makeForIndex() {
        return std::make_unique<Foo<I>>();
    }

    template<size_t... Is>
    auto makeFoo(size_t nIdx, std::index_sequence<Is...>) {
        using FuncType = std::unique_ptr<Base>(*)();
        constexpr FuncType arFuncs[] = { 
            detail::makeForIndex<Is>...
        };
        return arFuncs[nIdx]();
    }
}

auto makeFoo(size_t nIdx) {
    return detail::makeFoo(nIdx, std::make_index_sequence<SomeEnum::Last>());
}

```

This would not require template recursion either and is rather easy to understand. We create an array of function pointers and index into that using the runtime value provided by the caller.

Now you can create your `Foo<n>` like

```
size_t n;
...
auto ptr = makeFoo(n);

```
There is possibility to make it feasible. That is to use `tuple` which stores `std::make_unique` functions corresponding to enum size.

A helper method to generate the `tuple` using `index_sequence`

```
template<std::size_t... I>
auto generate(std::index_sequence<I...>)
{
    return std::make_tuple(std::make_unique<Foo<I>>...);
}

```

Next, to be able to iterate over it and find the index matching with the wanted value the recursive call is applied to increase it by 1.

```
template<std::size_t I = 0, typename... Tp, typename std::enable_if<I == sizeof...(Tp)>::type* = nullptr>
void make(const std::tuple<Tp...> &, std::unique_ptr<Base>&, int) // Unused arguments are given no names.
  { return;}

template<std::size_t I = 0, typename... Tp, typename std::enable_if<I < sizeof...(Tp)>::type* = nullptr>
void make(const std::tuple<Tp...>& t, std::unique_ptr<Base>& p, int value)
{
  if (value == I) {
    p = std::get<I>(t)();      
  }
  make<I + 1, Tp...>(t, p, value);
}

```

Combine two above methods, you can simply do

```
auto t = generate(std::make_index_sequence<4>{});
std::unique_ptr<Base> ptr{ nullptr };
int fooType = rand() % SomeEnum::Last;       
make(t, ptr, fooType);

```