Ваш код в основном имитирует виртуальный метод (небрежно говоря: тот же интерфейс, но реализация выбирается во время выполнения), поэтому ваш код может быть намного чище, если вы действительно используете виртуальный метод:
#include <memory>
struct base {
virtual double getValue(const int& x) const = 0;
};
struct impl1 : base {
double getValue(const int& x) { return 1.0; }
};
struct impl2 : base {
double getValue(const int& x) { return 2.0; }
};
// ... maybe more...
enum select { impl1s, impl2s };
base* make_impl( select s) {
if (s == impl1s) return new impl1();
if (s == impl2s) return new impl2();
}
int main() {
std::shared_ptr<base> x{ make_impl(impl1) };
}
Не уверен, что это то, что вы ищете. Кстати, использование <memory>
не должно заставлять вас чувствовать себя неуклюже, но вместо этого вы должны гордиться тем, что у нас есть такие замечательные инструменты в c ++;).
РЕДАКТИРОВАТЬ: Если вы не хотите, чтобы пользователь работал с (умными) указателями, оберните вышеупомянутое просто в другой класс:
struct foo {
shared_ptr<base> impl;
foo( select s) : impl( make_impl(s) ) {}
double getValue(const int& x) { return impl.getValue(x); }
};
теперь пользователь может сделать
int main() {
auto f1 { impl1s };
auto f2 { impl2s };
f1.getValue(1);
f2.getValue(2);
}