基于 conditional_t 超过 is_floating_point 的标签分发

tag dispatch based on conditional_t over is_floating_point

我收到一个奇怪的函数调用 'Equals',它在模板定义中既不可见,也不会通过参数相关查找找到,用于简单的标记分派实现。


template <typename T>
bool Equals(T lhs, T rhs){
    return Equals(rhs, lhs, conditional_t<is_floating_point<T>::value, true_type, false_type>{});
}

template <typename T> // for floating
bool Equals(T lhs, T rhs, true_type){
    return abs(lhs - rhs) < 0.01;
}

template <typename T> // for all the other
bool Equals(T lhs, T rhs, false_type){
    return lhs == rhs;
}

我做错了什么?

执行标签调度时,您没有实例化 true_type。但更重要的是,您需要更改函数的顺序,需要在执行调度的函数之前定义标记函数,例如:

template <typename T> // for floating
bool Equals(T lhs, T rhs, true_type){
    return abs(lhs - rhs) < 0.01;
}

template <typename T> // for all the other
bool Equals(T lhs, T rhs, false_type){
    return lhs == rhs;
}

// moved down here!
template <typename T>
bool Equals(T lhs, T rhs){
    return Equals(lhs, rhs, conditional_t<is_floating_point<T>::value, true_type{}, false_type>{});
}

也就是说,在 C++17 及更高版本中,您根本不需要使用标签调度,您可以使用 if constexpr 代替,例如:

template <typename T>
bool Equals(T lhs, T rhs){
    if constexpr (is_floating_point_v<T>)
        return abs(lhs - rhs) < 0.01;
    else
        return lhs == rhs;
}