I would like to improve the following runtime template selection code:
We have 4 functors for p-norm calculation (1 general case, 3 specialized cases). During runtime, we can select the best one.
template <typename T>
struct p_norm { // contains functors to calculate p-norm
struct general { ... }; // general case
struct one { ... }; // specialize for p=1
struct two { ... }; // specialize for p=2
struct inf { ... }; // specialize for p=inf
};
For example, we can get the distance based on p,
auto impl_fptr = distance_fn<T, p_norm<T>::general>;
if (p == 1.0) {
impl_fptr = distance_fn<T, p_norm<T>::one>;
} else if (p == 2.0) {
impl_fptr = distance_fn<T, p_norm<T>::two>;
} else if (std::isinf(p)) {
impl_fptr = distance_fn<T, p_norm<T>::inf>;
}
impl_fptr(vec1, vec2);
or maybe get the angle based on p,
auto impl_fptr = angle_fn<T, p_norm<T>::general>;
if (p == 1.0) {
impl_fptr = angle_fn<T, p_norm<T>::one>;
} else if (p == 2.0) {
impl_fptr = angle_fn<T, p_norm<T>::two>;
} else if (std::isinf(p)) {
impl_fptr = angle_fn<T, p_norm<T>::inf>;
}
impl_fptr(vec1, vec2);
The problem is that there are a lot of code duplications in selecting a suitable template case. I have no clue on how to improve the type selection.
OTOH, the minor problem is that I would like to implement p_norm<double> for the general case and implement p_norm<1.>, p_norm<2.>, ... for template specialization. I know it's not how the template works, but is there any way to make the specialization more obvious? Probably via tag dispatching?