“逆SFINAE”指的是:避免模棱两可的过载 [英] "Inverse SFINAE" to avoid ambiguous overload
问题描述
如果第二个模板实例化,如何防止下面的第一个模板实例化? (即,如果同时定义了 static_cast< T>(0)
和 T :: zero()
)
How can I prevent the first template below from instantiating if the second template instantiates? (i.e. if both static_cast<T>(0)
and T::zero()
are defined)
template<typename T>
auto zero() ->decltype(static_cast<T>(0)) {
return static_cast<T>(0);
}
template<typename T>
auto zero() ->decltype(T::zero()) {
return 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<int r>
struct rank : rank<r - 1> {};
template<>
struct rank<0> {};
template<typename T>
auto zero_impl(rank<0>) -> decltype(static_cast<T>(0)) {
return static_cast<T>(0);
}
template<typename T>
auto zero_impl(rank<1>) ->decltype(T::zero()) {
return T::zero();
}
template<typename T>
auto zero() { return zero_impl<T>(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.
这篇关于“逆SFINAE”指的是:避免模棱两可的过载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!