自定义有序集给出查找"invalid operator<"(...
Custom ordered set give "invalid operator<" of find(...)
当我试图在自定义有序集中找到元素时出现问题。
File: c:program files (x86)microsoft visual studio 10.0vcincludextree
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");
}
你的比较没有定义严格的弱排序
严格弱排序必须具有这些不变量(引用自上面的链接)
- 反身性 f(x, x)必须为假
- 反对称性 f (x, y)意味着! f (y, x)
- 动词的 f (x, y)和f (y, z)意味着f (x, z)。
- 等价的可传递性等价(如上所述)是可传递的:如果x等价于y, y等价于z,则x等价于z。(这意味着等价实际上满足等价关系的数学定义。)
你的
至少不符合非自反性(将一个对象与自身进行比较必须为假)和反对称性(如果x小于y,则y不小于x)基本上,<=
不是一个有效的排序,因为x <= x
返回true,这意味着你永远无法在集合中找到一个元素。为了找到一个元素,集合查找具有!cmp(key, element) && !cmp(element, key)
属性的元素,但这永远不能用于您的排序。
最简单的修复可能是将<=
更改为<
,但可能存在其他问题。
您的比较器可以是:
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;
}
你可以将两行替换为:
if (resultRhs == valueOrder.end()) return false;
if (resultLhs == valueOrder.end()) return true;
如果您希望在映射中不存在的字符串在此之前排序,
尝试将比较方法声明为const
,并为参数使用const引用。第一个修复是确保您可以使用OrderComarator
的常量版本调用方法,第二个修复是避免复制。
bool operator()( const string& lhs, const string& rhs ) const {
相关文章:
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- 'operator='已弃用:改用 QDir::setPath()
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- 过载'operator new'如何导致无限循环?
- C++ "error: invalid use of void expression"
- 与'operator='不匹配(操作数类型'String'且"void")
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- 收到错误"invalid use of non-static data member 'stu::n' "
- 处理"no operator found"
- 如何编写 operator= 用于使用虚拟方法与非平凡成员的匿名联合
- 运算符重载:"operator+"必须采用零个或一个参数
- 如何'Invalid conversion'和'no match for operator'更正这些 c++ 错误
- 为什么我会得到"Invalid use of :: (scope resolution operator)?"
- 排序 C++ - "invalid operator"
- 标准::设置比较器错误:"invalid operator<"
- STL 减少操作员和"invalid operator<"误差
- 自定义有序集给出查找"invalid operator<"(...
- 重载比较运算符C++会导致"invalid operator<"
- 具有额外参数'invalid operator <'的 c++ STL 排序