How can I prevent the first template below from instantiating if the second template instantiates? (i.e. if both static_cast and T::zero()
Without enable_if, relying on built-in rules of integer conversion ranks (conversion of 0 -> int is better than 0 -> char, which makes the former a first choice candidate, and the latter a viable second choice candidate):
template
auto zero_helper(char) -> decltype(static_cast(0))
{
return static_cast(0);
}
template
auto zero_helper(int) -> decltype(T::zero())
{
return T::zero();
}
template
auto zero() -> decltype(auto)
{
return zero_helper(0);
}
DEMO
With your own enable_if predicate (similar to the std::void_t technique):
#include
template
struct voider { using type = void; };
template
using void_t = typename voider::type;
template >
struct has_zero : std::false_type {};
template
struct has_zero> : std::true_type {};
template
auto zero()
-> typename std::enable_if::value, decltype(T::zero())>::type
{
return T::zero();
}
template
auto zero()
-> typename std::enable_if::value, T>::type
{
return static_cast(0);
}
DEMO 2