как использовать перегруженный std :: less для std :: map - PullRequest
5 голосов
/ 24 марта 2012

У меня есть следующий фрагмент:

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 *.Ребята, вы можете предложить способ сделать это?

Ответы [ 2 ]

8 голосов
/ 24 марта 2012

Несколько методов:
Примечание. Ни один из них не создает дополнительных копий, поскольку значения всегда передаются по ссылке (и, поскольку мы обычно не изменяем объект при сравнении, передается по ссылке).

Метод 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);
   }
};

метод 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);
   }
};

Метод 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;

Метод, который вы используете, будет зависеть от ситуации.
В большинствеситуации я бы использовал метод (1).Если существует особый порядок сортировки, который мне нужен для одного события, которое я хочу использовать с отсортированным контейнером, то я бы использовал метод (3).Метод (2) может использоваться в качестве альтернативы методу (1), и в некоторых ситуациях он лучше (но вам нужно предоставить больше подробностей об использовании, прежде чем я бы сказал, используйте это).

0 голосов
/ 29 сентября 2018

Вы ищете новые перегруженные версии find (), lower_bound () и upper_bound (), добавленные в C ++ 14.Они делают именно то, что вы просите.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...