If macros aren't your thing then you can also generate the if-then-else's using templates:
#include <stdexcept>
#include <iostream>
const unsigned int END_VAL = 10;
class MyClassInterface
{
public:
virtual double foo (double) = 0;
};
template<int P1, int P2, int P3>
class MyClass : public MyClassInterface
{
public:
double foo (double a)
{
return P1 * 100 + P2 * 10 + P3 + a;
}
};
struct ThrowError
{
static inline MyClassInterface* create (int c1, int c2, int c3)
{
throw std::runtime_error ("Could not create MyClass");
}
};
template<int DEPTH = 0, int N1 = 0, int N2 = 0, int N3 = 0>
struct Factory : ThrowError {};
template<int N2, int N3>
struct Factory<0, END_VAL, N2, N3> : ThrowError {};
template<int N1, int N3>
struct Factory<1, N1, END_VAL, N3> : ThrowError {};
template<int N1, int N2>
struct Factory<2, N1, N2, END_VAL> : ThrowError {};
template<int N1, int N2, int N3>
struct Factory<0, N1, N2, N3>
{
static inline MyClassInterface* create (int c1, int c2, int c3)
{
if (c1 == N1)
{
return Factory<1, N1, 0, 0>::create (c1, c2, c3);
}
else
return Factory<0, N1 + 1, N2, N3>::create (c1, c2, c3);
}
};
template<int N1, int N2, int N3>
struct Factory<1, N1, N2, N3>
{
static inline MyClassInterface* create (int c1, int c2, int c3)
{
if (c2 == N2)
{
return Factory<2, N1, N2, 0>::create (c1, c2, c3);
}
else
return Factory<1, N1, N2 + 1, N3>::create (c1, c2, c3);
}
};
template<int N1, int N2, int N3>
struct Factory<2, N1, N2, N3>
{
static inline MyClassInterface* create (int c1, int c2, int c3)
{
if (c3 == N3)
{
return new MyClass<N1, N2, N3> ();
}
else
return Factory<2, N1, N2, N3 + 1>::create (c1, c2, c3);
}
};
MyClassInterface* factory (int c1, int c2, int c3)
{
return Factory<>::create (c1, c2, c3);
}
Since the tests are nested it should be more efficient than sharth's macro solution.
You can extend it to more parameters by adding more depth cases.