0

对于简单的标记调度实现,我得到了一个奇怪的调用函数“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;
}

我究竟做错了什么?

4

1 回答 1

0

执行标签调度时,您没有实例化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;
}
于 2021-12-18T10:20:27.727 回答