簡體   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