I know, there are several topic, asking very close things but I don't get it to work in my case.
I would like to build a templated factory with index access during runtime. Therefore I have several types with the same base type. The factory gets the types which it is able to procude per template parameters. The call to the factory just gives an index. This is a small example:
#include <iostream>
#include <memory>
#include <tuple>
struct Base {
};
struct A : Base {
A(int) { std::cout << "A" << std::endl; }
};
struct B : Base {
B(int) { std::cout << "B" << std::endl; }
};
struct C : Base {
C(int) { std::cout << "C" << std::endl; }
};
template <typename ... Types>
struct Factory {
typedef std::tuple<Types...> TypesTuple;
std::shared_ptr<Base> operator ()(int index) {
return produce(index);
}
std::shared_ptr<Base> produce(int index) {
switch (index) {
case 0: return std::make_shared<typename std::tuple_element<0, TypesTuple>::type>(42);
case 1: return std::make_shared<typename std::tuple_element<1, TypesTuple>::type>(42);
}
throw;
}
};
//==============================================================================
int main() {
Factory<A, C> factory_ac;
auto a1 = factory_ac(0);
auto c1 = factory_ac(1);
Factory<A, B, C> factory_bc;
auto a2 = factory_bc(0);
auto b2 = factory_bc(1);
auto c2 = factory_bc(2);
}
I tried to overload the produce method with
template <typename = typename std::enable_if<std::tuple_size<TypesTuple>::value==2>::type>
counting up the size and providing the respective switch
statements, but this does not compile, overload not allowed.
I tried using https://stackoverflow.com/a/7383493/2524462 but I couldn't get it to work, because the parameter packs don't expand with a lambda and wrapping it in a template function I get problems with the constexpr
array, since I don't have trivial types.
Boost MPL for_each
comes to mind, but I got problems compiling, because my types are not trivially constructable.
So how would one change the factory to get the main to compile and work?