How can I prevent the first template below from instantiating if the second template instantiates? (i.e. if both static_cast and T::zero()
If you need to extend it to multiple overloads with fine grained control of overload rank, a common technique is to use tag dispatching.
template
struct rank : rank {};
template<>
struct rank<0> {};
template
auto zero_impl(rank<0>) -> decltype(static_cast(0)) {
return static_cast(0);
}
template
auto zero_impl(rank<1>) ->decltype(T::zero()) {
return T::zero();
}
template
auto zero() { return zero_impl(rank<10>{}); }
Derived to base conversions will prefer the closest base class. Which translates to calling the overload with the highest rank. Since that one will have the best implicit conversion sequence in the eyes of the compiler.