繁体   English   中英

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

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

我有以下片段:

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

当我尝试这个时,我得到一个错误:错误:没有匹配的函数调用std::map<COR, SomeStruct*, std::less<COR>, std::allocator<std::pair<const COR, SomeStruct*> > >::find(const char*&)

我不想使用任何涉及比较两个“COR”对象的方法。 我将比较 COR 和 const char*。 各位大佬能推荐一下方法吗?

几种方法:
注意:这些都不会生成额外的副本,因为值总是通过引用传递(并且因为我们通常不会在通过常量引用进行比较时改变对象)。

方法一:

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

方法二:

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

方法三:

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;

您使用的方法将取决于情况。
在大多数情况下,我会使用方法(1)。 如果我想与排序容器一起使用的一次性事件需要特殊排序顺序,那么我将使用方法 (3)。 方法 (2) 可以用作方法 (1) 的替代方法,并且在某些情况下更好(但在我说使用此方法之前,您需要提供有关使用的更多详细信息)。

您收到此错误是因为您犯了一个错误 -std::less operator()的参数类型必须相同。 所以,这有效:

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

您正在寻找 C++14 中添加的 find()、lower_bound() 和 upper_bound() 的新重载版本。 他们完全按照你的要求去做。

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

暂无
暂无

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

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