dor*_*mon 2 c++ templates sfinae c++11
我正在尝试创建一个类型化的比较函数,为不同类型进行一些自定义比较.
#include <type_traits>
template <typename T>
bool typedCompare(const T& lhs, const T& rhs)
{
return lhs == rhs; // default case, use ==
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
typedCompare(const T& lhs, const T& rhs)
{
return (lhs - rhs) < 1e-10;
}
int main()
{
typedCompare(1, 1);
typedCompare(1.0, 1.0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这里,我有一个特殊的版本double比较少量的差异(请忽略我没有使用的事实std::abs()).我有一些其他自定义类型,我需要做一些特殊的比较,我不能==因为某些原因改变他们的运算符.
此外,我仍然希望拥有一个采用==操作员的"全能"风格功能.我的问题是,在尝试编译此代码片段时,编译器抱怨这typedCompare(1.0, 1.0)是不明确的,它可以选择提供的两个函数中的任何一个.
为什么?我怎么能解决这个问题?
谢谢.
为什么?
简而言之,您使用的SFINAE不正确,因此当您呼叫typedCompare双打时,两个功能模板都有效.
我怎么能解决这个问题?
在这种特殊情况下,修复SFINAE以使其正常工作:
template <typename T>
typename std::enable_if<!std::is_floating_point<T>::value, bool>::type
typedCompare(const T& lhs, const T& rhs)
{
return lhs == rhs; // default case, use ==
}
template <typename T>
typename std::enable_if<std::is_floating_point<T>::value, bool>::type
typedCompare(const T& lhs, const T& rhs)
{
return (lhs - rhs) < 1e-10;
}
Run Code Online (Sandbox Code Playgroud)
请注意,此解决方案在许多类型的自定义方面不是那么好.另一种方法是使用标签分派:
struct floating_point_tag {};
// other tags
template <typename T>
bool typedCompare(const T& lhs, const T& rhs, floating_point_tag) {
return (lhs - rhs) < 1e-10;
}
// implementations for other tags
template <typename T>
bool typedCompare(const T& lhs, const T& rhs) {
if (std::is_floating_point<T>::value) {
return typedCompare(lhs, rhs, floating_point_tag{});
}
// other checks here
return lhs == rhs;
}
Run Code Online (Sandbox Code Playgroud)
最后,使用C++ 17,您可以使用if constexpr:
template <typename T>
bool typedCompare(const T& lhs, const T& rhs) {
if constexpr (std::is_floating_point<T>::value) {
return (lhs - rhs) < 1e-10;
} else { // add other if-else here
return lhs == rhs;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
188 次 |
| 最近记录: |