如何使用重载std :: less为std :: map [英] how to use overloaded std::less for std::map

查看:197
本文介绍了如何使用重载std :: less为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 //我不想使用它,因为它会创建一个临时对象
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 *。

解决方案

有几种方法:

注意:这些都不是生成额外的副本,因为值总是通过引用传递(并且因为我们通常不会通过比较传递通过const引用来变换对象)。



方法1: h3>

  class COR 
{
public:
// 1:使其成为成员函数
//因此你只需要指定右边。
//左边是隐式的。
bool operator<(COR const& right)const
{
return(strcmp(m_or,right.m_or)< 0);
}
};



方法2:



  class COR 
{
public:
// 2:设为好友非成员函数
//注意:因为我在这里声明使它成为类的一部分。
//这是一个单独的非成员函数
//编译器因为'friened'而产生命运
friend bool operator<(COR const& left,COR const& right)
{
return(strcmp(left.m_or,right.m_or)< 0);
}
};方法3:








$ b < class COR
{
public:
//只是一个例子。只需要一些方法为函子访问成员
//在一种方式,将允许严格的弱排序。
bool test(COR const& right)const {return(strcmp(m_or,right.m_or)< 0);}
};

//定义函子。
//这只是一个带有operator()重载的类,所以它可以
//像一个函数。你可以让它做任何你喜欢的,但对于
//比较它将传递容器的两个成员(接受const
//引用,并确保函子是const成员,事情会很好)。
struct CorTest
{
bool operator()(COR const& left,COR const& right)const
{
return left.test(right);
}
};

//当你声明你刚刚传递的集合作为第二个模板参数。
//(如果是地图,则为第三个)
std :: set< COR,CorTest> mySet;
std :: map< COR,int,CorTest> myMap;

您使用的方法将取决于具体情况。

在大多数情况下,使用方法(1)。如果有一个特殊的排序顺序,我需要一个关闭事件,我想使用一个排序的容器,然后我会使用方法(3)。方法(2)可以作为方法(1)的替代方法,在某些情况下是更好的(但是你需要提供更多关于使用的细节,之后我会说使用这个)。


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*&)

I do not want to use any method that involves comparison of two "COR" objects. I will have comparison of COR with 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). 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). 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).

这篇关于如何使用重载std :: less为std :: map的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆