I want to construct an object of a type which is selected at runtime based on an enum class value. The classes A and B have multiple constructors with various numbers of arguments which may be used at runtime. I have attempted this problem by trying to write a factory method returning a shared_ptr to the base class.
Here is my ill-formed attempt:
enum class Type
{
A,
B // C, etc
};
struct Base{};
struct A : public Base
{
A(const int a) { std::cout << "A::A(int)"; }
A(double d) { std::cout << "A::A(double)"; }
A(int a, double d) { std::cout << "A::A(int,double)"; }
};
struct B : public Base
{
B(int i, double d) { std::cout << "B::B(double)"; }
B(int a, double d, double dd) { std::cout << "B::B(int,double, double)"; }
};
template <typename... Args>
std::shared_ptr<Base> make_Type(Type t, Args &&...args)
{
if (t == Type::A)
return std::make_shared<A>(std::forward<Args>(args)...);
else if (t == Type::B)
return std::make_shared<B>(std::forward<Args>(args)...);
else
assert(false);
}
No doubt, this doesn't work as the following call triggers a compilation error as the other branch for B doesn't have any constructor with single argument:
make_Type(Type::A,1);
gcc14 returns the following:
error: no matching function for call to 'B::B(int)'
I can create a static version with if constexpr. But how to attempt a runtime version? (Possibly without using typeinfo).
Any alternative approach is also welcome.
make_Type(Type::A,1)as the other branch now doesn't compile as B doesn't have a compatible constructor taking single arg.