在我尝试在自定义有序集中查找元素时出现问题。
File: c:\program files (x86)\microsoft visual studio 10.0\vc\include\xtree
Line: 1746
Expression: invalid operator<
我需要一组字符串,其中元素按照我的需要进行排序。
比较者对象:
struct OrderComparator {
public:
static map<string,int> valueOrder;
bool operator()( const string lhs, const string rhs ) {
map<string,int>::iterator resultLhs,resultRhs;
resultLhs = valueOrder.find(lhs);
resultRhs = valueOrder.find(rhs);
if (resultLhs == valueOrder.end() || resultRhs == valueOrder.end())
{
return false;
}
else {
bool result = resultLhs->second <= resultRhs->second;
return result;
}
}
static map<string,int> create_map()
{
map<string,int> m;
m["A"] = 1;
m["B"] = 2;
m["C"] = 3;
m["D"] = 4;
return m;
}
};
比较者工作正常!
但是当我试图在设置中提到错误时。
typedef set<string, OrderComparator> TREESET_CMP;
...
TREESET_CMP::iterator it = myTree.find(obj); <-fails
...
如果有人可以告诉我为什么会发生这种情况以及如何解决这个问题,那将会很高兴。
全功能迷你示例:
#include "stdafx.h"
#include <string>
#include <set>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;
#include <stdio.h>
#include <tchar.h>
struct OrderComparator {
public:
static map<string,int> valueOrder;
bool operator()( const string lhs, const string rhs ) {
map<string,int>::iterator resultLhs,resultRhs;
resultLhs = valueOrder.find(lhs);
resultRhs = valueOrder.find(rhs);
if (resultLhs == valueOrder.end() || resultRhs == valueOrder.end())
{
return false;
}
else {
bool result = resultLhs->second <= resultRhs->second;
return result;
}
}
static map<string,int> create_map()
{
map<string,int> m;
m["A"] = 1;
m["B"] = 2;
m["C"] = 3;
m["D"] = 4;
return m;
}
};
map<string,int> OrderComparator::valueOrder = OrderComparator::create_map();
typedef set<string, OrderComparator> TREESET_CMP;
int _tmain(int argc, _TCHAR* argv[])
{
TREESET_CMP myTree;
myTree.insert("B");
myTree.insert("C");
myTree.insert("A");
TREESET_CMP::const_iterator it = myTree.find("A");
system("PAUSE");
}
答案 0 :(得分:3)
您的比较未定义strict weak ordering
严格的弱排序必须具有这些不变量(引自上面的链接)
你的失败至少是自反性(比较一个物体与自身必须是假的)和反对称性(如果x小于y,那么y不小于x)
基本上,<=
不是有效排序,因为x <= x
返回true,这意味着您永远无法在集合中找到元素。要查找元素,集合将查找具有属性!cmp(key, element) && !cmp(element, key)
的元素,但这对于您的订购无效。
最简单的解决方法可能是将<=
更改为<
,但可能还有其他问题。
答案 1 :(得分:1)
您的比较器可以是:
bool operator()( const string &lhs, const string &rhs ) {
map<string,int>::iterator resultLhs,resultRhs;
resultLhs = valueOrder.find(lhs);
resultRhs = valueOrder.find(rhs);
if (resultLhs == valueOrder.end()) return false;
if (resultRhs == valueOrder.end()) return true;
return resultLhs->second < resultRhs->second;
}
您可以将2行替换为:
if (resultRhs == valueOrder.end()) return false;
if (resultLhs == valueOrder.end()) return true;
如果您希望在此之前对地图中不存在的字符串进行排序。
答案 2 :(得分:0)
尝试将比较方法声明为const
并使用const引用作为参数。第一个修复是确保您可以使用OrderComarator
的常量版本调用您的方法,第二个修复是避免复制。
bool operator()( const string& lhs, const string& rhs ) const {