Вы можете написать конструктор, принимающий что угодно, а затем делегировать все, что предоставляют политики:
// "Tag" and "No" are used to make the class/function unique
// (makes the using declarations work with GCC).
template<int Tag>
struct No { void init(No); };
template<typename P1 = No<0>, typename P2 = No<1>, typename P3 = No<2> >
struct Magic : P1, P2, P3 {
template<typename T>
Magic(T t) {
init(t);
}
private:
using P1::init;
using P2::init;
using P3::init;
};
Теперь, как только вы передадите аргумент, компилятор определит лучшее соответствие среди политик:
struct IntPolicy { void init(int) { std::cout << "called int!"; } };
struct FloatPolicy { void init(float) { std::cout << "called float!"; } };
Magic<IntPolicy, FloatPolicy> m(0), n(0.0f);