我有以下代码段:
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 *进行比较。你们能建议一种方法吗?
答案 0 :(得分:9)
几种方法:
注意:这些都不会产生额外的副本,因为值总是通过引用传递(并且因为我们通常不会通过const引用在比较传递中改变对象)。
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)的替代方法,并且在某些情况下更好(但是在我说使用它之前你需要提供有关使用的更多细节)。
答案 1 :(得分:0)
您正在寻找C ++ 14中添加的find(),lower_bound()和upper_bound()的新重载版本。他们正是您要的。
答案 2 :(得分:0)
发生此错误是因为您犯了一个错误-std::less
operator()
的参数类型必须相同。因此,这可行:
template <>
struct std::less<COR>
{
bool operator()(const COR &a, const COR &b) const { return (strcmp(a.GetOR(), b.GetOR()) < 0); }
};