Возможное решение состоит в том, чтобы составить все возможные комбинации и выбрать правильную:
template <typename T1, T2>
void f() {
Module<T1, T2> module;
std::cout << module.subModule1.Apply(3) + module.subModule2.Apply(2) << std::endl;
}
int main()
{
int type1 = userChoice();
int type2 = userChoice();
std::array<void(*)(), 9> fs = {
&f<Add, Add>, &f<Add, Multiply>, &f<Add, Divide>,
&f<Multiply, Add>, &f<Multiply, Multiply>, &f<Multiply, Divide>,
&f<Divide, Add>, &f<Divide, Multiply>, &f<Divide, Divide>,
}
fs[type1 + 3 * type2]();
}
Массив может быть даже создан с помощью некоторого метапрограммирования.
Но я думаю, что простой полиморфизм (как ответ Дана) достаточно хорош.