Search code examples
c++dictionarycachingkeyglm-math

binary '<': no operator found which takes a left-hand operand of type 'const _Ty' glm::vec3 in map


I've been dabbling with discregrids LRUCache, but I'm having trouble getting it working with glm's vec3's. I keep getting a binary '<': no operator found which takes a left-hand operand of type 'const _Ty' error, even though I've implemented an operator overload for the underlying std:map [file.hpp]:

bool operator<(const glm::vec3& lhs, const glm::vec3& rhs)
{
    return lhs.x < rhs.x || lhs.x == rhs.x && (lhs.y < rhs.y || lhs.y == rhs.y && lhs.z < rhs.z);
}

template <typename K, typename V>
class LRUCache
{
    using key_type = K;
    using value_type = V;

    using key_tracker_type = std::list<key_type>;
    using key_to_value_type = std::map<key_type, std::pair<value_type, typename key_tracker_type::iterator>>;
    ...
}
LRUCache<glm::vec3, double>

Solution

  • The short form is your operator< is not being found due to how ADL works. In particular, C++ searches the namespaces of the arguments (and their base classes, and other related classes). You've placed operator< in the global namespace, which is not the glm namespace.

    So, you could either put the comparison in the glm namespace (Which I don't really recommend), or create a comparison function object, and use that.

    struct MyCompare{
      bool operator()(const glm::vec3& lhs, const glm::vec3& rhs) const
      {
         return lhs.x < rhs.x || lhs.x == rhs.x && (lhs.y < rhs.y || lhs.y == 
         rhs.y && lhs.z < rhs.z);
      }
    };
    

    And then use it with

    std::map<key_type, std::pair<value_type, typename key_tracker_type::iterator>, MyCompare>
    

    If you don't want ordering, you can also look at unordered_map, if you can develop a reasonable hashing function (or if it comes with one).