如何为集合 C++ 建立比较器
How do I establish a comparator for a set c++
我有一套,对于这套,我需要两个不同的比较器。例如,对于集合 frontier
我需要按成本排序,但我有另一个集合 board
需要按坐标排序。我知道你 可以 使用比较器作为第二个参数为每个集合定义一个比较器,但我已经试过了,它给了我一个错误。
我尝试使用的代码:
struct tile {
int id;
int xCord;
int yCord;
int cost;
...
bool operator<(const tile& Rhs) const {
if (cost < Rhs.cost) {
return true;
}
else if (cost < Rhs.cost) {
return false;
}
else {
if (id < Rhs.id) {
return true;
}
else
return false;
}
}
...
};
我用于比较器的另一个结构(我知道这很可能是不正确的,这就是我寻求帮助的原因。):
struct costComp {
int id;
int xCord;
int yCord;
int cost;
costComp() {}
costComp(int a, int b, int c, int d = 0) :
id(a),
xCord(b),
yCord(c),
cost(d) {}
bool operator<( const tile& Rhs) const {
if (xCord < Rhs.xCord)
return true;
else if (xCord < Rhs.xCord)
return false;
else {
if (yCord < Rhs.yCord)
return true;
else if (yCord < Rhs.yCord)
return false;
else
return false;
}
}
};
然后,我将集合定义为:
set<tile,costComp> startBoard;
我得到的错误:
c2064: term does not evaluate to a function taking 2 arguments
非常感谢任何帮助。
std::set
中的 Compare
参数旨在成为一些可以用 (const tile&, const tile&)
调用的可调用类型。这意味着您可以使用重载 operator()
的仿函数,例如,像这样:
struct Comp {
bool operator()(const tile& lhs, const tile& rhs) const {
if (lhs.id < rhs.id) return true;
if (lhs.id > rhs.id) return false;
if (lhs.xCord < rhs.xCord) return true;
if (lhs.xCord > rhs.xCord) return false;
if (lhs.yCord < rhs.yCord) return true;
if (lhs.yCord > rhs.yCord) return false;
return lhs.cost < rhs.cost;
}
// or maybe, if this logic already exists:
bool operator()(const tile& lhs, const tile& rhs) const {
return lhs < rhs; // invoke tile::operator<(const tile&)
}
};
...
std::set<tile, Comp> myset;
这样,比较器结构就不需要跟踪任何一个 tile
对象的细节,并且可以删除 costComp
的冗余成员。
如果您希望比较器是可配置的,您可以将成员添加到 Comp
结构定义中,并在实例化集合时在构造函数调用中初始化它们:
struct Comp {
Comp(bool use_cost = false /* default behavior */) : m_use_cost(use_cost) {}
bool operator()(const tile& lhs, const tile& rhs) const {
if (m_use_cost){
return lhs.cost < rhs.cost;
} else {
...
}
}
private:
const bool m_use_cost;
};
...
// default comparison, won't use cost
std::set<tile, Comp> setA;
// specify custom behaviour
std::set<tile, Comp> setB {Comp{true /* right here */}};
显然,可配置性不限于一个或多个bools
。让一些 enum
具有 SortByCost
、SortByXcoord
这样的值可能是有意义的。或者,您可以有一个单独的函子结构来执行每个操作,但这意味着具有不同比较器的集合将具有不同的类型,并且不能相互复制或移动。
我有一套,对于这套,我需要两个不同的比较器。例如,对于集合 frontier
我需要按成本排序,但我有另一个集合 board
需要按坐标排序。我知道你 可以 使用比较器作为第二个参数为每个集合定义一个比较器,但我已经试过了,它给了我一个错误。
我尝试使用的代码:
struct tile {
int id;
int xCord;
int yCord;
int cost;
...
bool operator<(const tile& Rhs) const {
if (cost < Rhs.cost) {
return true;
}
else if (cost < Rhs.cost) {
return false;
}
else {
if (id < Rhs.id) {
return true;
}
else
return false;
}
}
...
};
我用于比较器的另一个结构(我知道这很可能是不正确的,这就是我寻求帮助的原因。):
struct costComp {
int id;
int xCord;
int yCord;
int cost;
costComp() {}
costComp(int a, int b, int c, int d = 0) :
id(a),
xCord(b),
yCord(c),
cost(d) {}
bool operator<( const tile& Rhs) const {
if (xCord < Rhs.xCord)
return true;
else if (xCord < Rhs.xCord)
return false;
else {
if (yCord < Rhs.yCord)
return true;
else if (yCord < Rhs.yCord)
return false;
else
return false;
}
}
};
然后,我将集合定义为:
set<tile,costComp> startBoard;
我得到的错误:
c2064: term does not evaluate to a function taking 2 arguments
非常感谢任何帮助。
std::set
中的 Compare
参数旨在成为一些可以用 (const tile&, const tile&)
调用的可调用类型。这意味着您可以使用重载 operator()
的仿函数,例如,像这样:
struct Comp {
bool operator()(const tile& lhs, const tile& rhs) const {
if (lhs.id < rhs.id) return true;
if (lhs.id > rhs.id) return false;
if (lhs.xCord < rhs.xCord) return true;
if (lhs.xCord > rhs.xCord) return false;
if (lhs.yCord < rhs.yCord) return true;
if (lhs.yCord > rhs.yCord) return false;
return lhs.cost < rhs.cost;
}
// or maybe, if this logic already exists:
bool operator()(const tile& lhs, const tile& rhs) const {
return lhs < rhs; // invoke tile::operator<(const tile&)
}
};
...
std::set<tile, Comp> myset;
这样,比较器结构就不需要跟踪任何一个 tile
对象的细节,并且可以删除 costComp
的冗余成员。
如果您希望比较器是可配置的,您可以将成员添加到 Comp
结构定义中,并在实例化集合时在构造函数调用中初始化它们:
struct Comp {
Comp(bool use_cost = false /* default behavior */) : m_use_cost(use_cost) {}
bool operator()(const tile& lhs, const tile& rhs) const {
if (m_use_cost){
return lhs.cost < rhs.cost;
} else {
...
}
}
private:
const bool m_use_cost;
};
...
// default comparison, won't use cost
std::set<tile, Comp> setA;
// specify custom behaviour
std::set<tile, Comp> setB {Comp{true /* right here */}};
显然,可配置性不限于一个或多个bools
。让一些 enum
具有 SortByCost
、SortByXcoord
这样的值可能是有意义的。或者,您可以有一个单独的函子结构来执行每个操作,但这意味着具有不同比较器的集合将具有不同的类型,并且不能相互复制或移动。