Не уверен, что это именно то, что вам нужно, но вы можете попробовать это:
template <typename T>
class Selector; // implement this one as well, if you want to have a default...
template <> class Selector<int> { public: using Type = ClassX; };
template <> class Selector<double> { public: using Type = ClassY; };
template<typename U>
void func(U var)
{
using T = typename Selector<U>::Type;
};
Вариант:
template<typename U, typename T = typename Selector<U>::Type>
void func(U var) { }
Это позволит заменить выбранный тип, если это необходимо:
func(12); // uses default: ClassX
func<int, ClassZ>(10); // replace ClassX with ClassZ