简体   繁体   English

如何为 std::map 使用重载的 std::less

[英]how to use overloaded std::less for std::map

I have the following snippet:我有以下片段:

typedef char OR[12];

class COR
{
   OR m_or;
public:
   COR(const char* or) { strcpy(m_or, or); }
   COR(const COR& o) { strcpy(m_or, o.m_or); }
   const char* GetOR() const { return m_or; }

#if 0 // I do not wish to use this as it will create a temporary object
   bool operator<(const COR& left, const COR& right) const 
   { return (strcmp(left.m_or, right.m_or) < 0); }
#endif
};

namespace std {
   template<>
   struct less<COR> {
       bool operator()(const COR& cor, const char* or) const 
       { return (strcmp(cor.GetOR(), or) < 0); }
   };
}

When I try this I get an error: error: no matching function for call to std::map<COR, SomeStruct*, std::less<COR>, std::allocator<std::pair<const COR, SomeStruct*> > >::find(const char*&)当我尝试这个时,我得到一个错误:错误:没有匹配的函数调用std::map<COR, SomeStruct*, std::less<COR>, std::allocator<std::pair<const COR, SomeStruct*> > >::find(const char*&)

I do not want to use any method that involves comparison of two "COR" objects.我不想使用任何涉及比较两个“COR”对象的方法。 I will have comparison of COR with const char*.我将比较 COR 和 const char*。 Can you guys suggest a way to do it?各位大佬能推荐一下方法吗?

Several methods:几种方法:
Note: None of these generate extra copies as the values are always passed by reference (and since we don't normally mutate an object on comparison pass by const reference).注意:这些都不会生成额外的副本,因为值总是通过引用传递(并且因为我们通常不会在通过常量引用进行比较时改变对象)。

Method 1:方法一:

class COR
{
   public:
   // 1: Make it a member function
   //    Thus you only specify the right hand side.
   //    The left is implicit.
   bool operator<(COR const& right) const 
   {
       return (strcmp(m_or, right.m_or) < 0);
   }
};

method 2:方法二:

class COR
{
   public:
   // 2: Make it a friend non member function
   //    Note: Just because I declare it here does not make it part of the class.
   //          This is a separate non member function
   //          The compiler makes the destinction because of the `friened`
   friend bool operator<(COR const& left, COR const& right) 
   {
       return (strcmp(left.m_or, right.m_or) < 0);
   }
};

Method 3:方法三:

class COR
{
    public:
    // Just an example. Just need some way for the functor to access members
    //                  In a way that will allow a strict weak ordering.
    bool test(COR const& right) const {return (strcmp(m_or, right.m_or) < 0);}
};

// Define a functor.
//        This is just a class with the operator() overloaded so that it can 
//        act like a function. You can make it do whatever you like but for
//        comparisons it will be passed two members of the container (accept by const
//        reference and make sure the functor is const member and things will go well).
struct CorTest
{
    bool operator()(COR const& left, COR const& right) const
    {
        return left.test(right);
    }
};

// When you declare the set you just pass as the second template parameter.
//  (or third if it is a map)
std::set<COR, CorTest>        mySet;
std::map<COR, int, CorTest>   myMap;

The method you use will depend on situation.您使用的方法将取决于情况。
In most situations I would use method (1).在大多数情况下,我会使用方法(1)。 If there is a special sort order I needed for a one off event that I want to use with a sorted container then I would use method (3).如果我想与排序容器一起使用的一次性事件需要特殊排序顺序,那么我将使用方法 (3)。 method (2) can be used as an alternative to method (1) and in some situations is better (but you need to provide more details about usage before I would say use this).方法 (2) 可以用作方法 (1) 的替代方法,并且在某些情况下更好(但在我说使用此方法之前,您需要提供有关使用的更多详细信息)。

You got this error because you made a mistake - the arguments type of thestd::less operator() must be identical.您收到此错误是因为您犯了一个错误 -std::less operator()的参数类型必须相同。 So, this works:所以,这有效:

template <>
struct std::less<COR>
{
    bool operator()(const COR &a, const COR &b) const { return (strcmp(a.GetOR(), b.GetOR()) < 0); }
};

You're looking for the new overloaded versions of find(), lower_bound(), and upper_bound() added in C++14.您正在寻找 C++14 中添加的 find()、lower_bound() 和 upper_bound() 的新重载版本。 They do exactly what you are asking for.他们完全按照你的要求去做。

https://en.cppreference.com/w/cpp/container/set/find https://en.cppreference.com/w/cpp/container/set/find

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM