0

I am getting a strange, Call to function 'Equals' that is neither visible in the template definition nor found by argument-dependent lookup, for a simple tag dispatch implementation.


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;
}

what am I doing wrong?

Atta Oveisi
  • 21
  • 2
  • 8
  • I am not sure what you mean by how you get it! by calling: bool b = Equals(1.2f, 1.2f); – Atta Oveisi Dec 18 '21 at 10:39
  • Note that instead of `conditional_t::value, true_type, false_type>{}` you could just write `is_floating_point{}`. – Evg Dec 18 '21 at 14:41

1 Answers1

1

When performing the tag dispatching, you are not instantiating the true_type. But more importantly, you need to change the order of your functions, the tagged functions need to be defined before the function that is performing the dispatching, eg:

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>{});
}

That being said, in C++17 and later, you don't need to use tag dispatching at all, you can use if constexpr instead, eg:

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;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770