C++ 声明函子进行比较?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1765539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Declaring functors for comparison?
提问by Goles
I have seen other people questions but found none that applied to what I'm trying to achieve here.
我见过其他人的问题,但没有发现适用于我在这里尝试实现的目标。
I'm trying to sort Entities via my EntityManager class using std::sort and a std::vector<Entity *>
我正在尝试使用 std::sort 和一个通过我的 EntityManager 类对实体进行排序 std::vector<Entity *>
/*Entity.h*/
class Entity
{
public:
float x,y;
};
struct compareByX{
bool operator()(const GameEntity &a, const GameEntity &b)
{
return (a.x < b.x);
}
};
/*Class EntityManager that uses Entitiy*/
typedef std::vector<Entity *> ENTITY_VECTOR; //Entity reference vector
class EntityManager: public Entity
{
private:
ENTITY_VECTOR managedEntities;
public:
void sortEntitiesX();
};
void EntityManager::sortEntitiesX()
{
/*perform sorting of the entitiesList by their X value*/
compareByX comparer;
std::sort(entityList.begin(), entityList.end(), comparer);
}
I'm getting a dozen of errors like
我收到了十几个错误,比如
: error: no match for call to '(compareByX) (GameEntity* const&, GameEntity* const&)'
: note: candidates are: bool compareByX::operator()(const GameEntity&, const GameEntity&)
I'm not sure but ENTITY_VECTOR is std::vector<Entity *>
, and I don't know if that could be the problem when using the compareByX functor ?
我不确定,但 ENTITY_VECTOR 是std::vector<Entity *>
,我不知道这是否是使用 compareByX 函子时的问题?
I'm pretty new to C++, so any kind of help is welcome.
我对 C++ 很陌生,所以欢迎任何形式的帮助。
采纳答案by xtofl
And a third one comes in... After you edited you question, still one open topic: your comparator takes a const &
to the GameEntity
class. It should, in order to work with the values of the vector<GameEntity*>
, take const GameEntity*
arguments instead.
第三个进来......在你编辑了你的问题之后,仍然是一个开放的主题:你的比较器将 aconst &
带到GameEntity
课堂上。它应该,为了与工作的价值vector<GameEntity*>
,采取 const GameEntity*
的参数来代替。
回答by Jerry Coffin
A functor is a class that defines operator() so an object of that class can be "invoked" with the same syntax as calling a function:
函子是一个定义 operator() 的类,因此可以使用与调用函数相同的语法“调用”该类的对象:
struct functor {
bool operator()(Entity const &a, Entity const &b) {
return a.x < b.x;
}
};
If you want that as a member of your Entity class, you'd use a nested class:
如果您希望将其作为 Entity 类的成员,则可以使用嵌套类:
class Entity {
float x;
public:
friend class byX;
class byX {
bool operator()(Entity const &a, Entity const &b) {
return a.x < b.x;
}
};
};
Then your sort would look something like this:
那么你的排序看起来像这样:
std::sort(ManagedEndities.begin(), ManagedEntities.end(), Entity::byX());
Alternatively, if you usually sort Entities by X, you could define operator< for Entity:
或者,如果您通常按 X 对实体进行排序,则可以为实体定义 operator<:
class Entity {
float x;
public:
bool operator<(Entity const &other) {
return x < other.x;
}
};
In this case, your use of sort would be a bit simpler:
在这种情况下,您对 sort 的使用会更简单一些:
std::sort(ManagedEntities.begin(), ManagedEntities.end());
Creating the comparison function as a normal member function of the Entity class, however, will lead to a sort invocation that's pretty ugly -- it'll usually need something like std::mem_fun_ref to do the job; it's sufficiently ugly that I'd generally avoid it for real code.
然而,将比较函数创建为 Entity 类的普通成员函数会导致排序调用非常丑陋——它通常需要像 std::mem_fun_ref 这样的东西来完成这项工作;它非常丑陋,我通常会在真正的代码中避免使用它。
回答by xtofl
In the light of 'what you're trying to achieve', I may do another guess... You want to be able to specify whether to compare your objects by their GameEntity::x
member, or by their GameEntity::y
member.
根据“您要实现的目标”,我可能会做另一个猜测……您希望能够指定是按GameEntity::x
成员还是按GameEntity::y
成员比较对象。
The easiest way would be to, as you did, specify a functor for each member:
最简单的方法是,像您一样,为每个成员指定一个函子:
struct CompareX {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.x < b.x;
}
};
struct CompareY {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.y < b.y;
}
};
CompareX compx; // create a compare object
std::sort( v.begin(), v.end(), compx );
The 'flexible' yet more cumbersome way would be to create a template functor:
“灵活”但更麻烦的方法是创建一个模板函子:
#include <iostream>
using namespace std;
// a mockup of your class
struct GameEntity { float x, y, z; };
// just to be able to print it...
ostream& operator<<( ostream& o, const GameEntity& g ) {
return o << "(" << g.x << ", " << g.y << ", " << g.z << ")";
}
// cumbersome starts here...
typedef float (GameEntity::*membervar);
// a 'generic' float-member comparator
template< membervar m > struct CompareBy {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.*m < b.*m ;
}
};
// example code
int main() {
using namespace std;
GameEntity v[] = { {1,0,0}, {2,0,1}, {3,-1,2} };
GameEntity* vend = v + sizeof(v)/sizeof(v[0]);
sort( v, vend, CompareBy< &GameEntity::x >() );
copy( v, vend, ostream_iterator<GameEntity>( cout, "\n" ) );
}
回答by xtofl
I did see this question, recently, though....
不过,最近我确实看到了这个问题......
The answer was something in the way of: the function provided to sort
should not be a member-function of something. Meaning: it should be a static function, or a free function. In case you declare it a static function, you should still precede it by Entity::compareByX
in order to name it correctly.
答案是这样的:提供给的函数sort
不应该是某个东西的成员函数。含义:它应该是一个静态函数,或者一个自由函数。如果您将其声明为静态函数,您仍应在其前面加上Entity::compareByX
以正确命名。
If you define the order in the class itself, you can, as aJ already said, use a function adapter mem_fun
or mem_fun_ref
to pour it into a 'free' functor object.
如果您在类本身中定义顺序,则可以如 aJ 已经说过的那样,使用函数适配器mem_fun
或mem_fun_ref
将其倒入“自由”函子对象中。
If you want an Entity
object to do the comparison, you should provide sort
with an object (called a functor or comparator in this case):
如果您想要一个Entity
对象进行比较,您应该提供sort
一个对象(在这种情况下称为函子或比较器):
struct EntityComp {
bool operator()( const GameEntity& a, const GameEntity& b ) const {
return a.x < b.x;
}
}
...
std::sort( v.begin(), v.end(), EntityComp() );
回答by Elalfer
回答by Fox
try this..
尝试这个..
class CompareByX
{
operator ()(const GameEntity &a, const GameEntity &b) { ... };
};
...
std::sort( this->begin(), this->end(), CompareByX);
In a nutshell, a functor is a function object - the STL looks specifically for an operator () that takes in the two parameters I've specified. If you're new to C++, I suggest you look up operators and functors - they're pretty handy even outside STL.
简而言之,函子是一个函数对象——STL 专门寻找一个运算符 (),它接受我指定的两个参数。如果您不熟悉 C++,我建议您查找运算符和函子 - 即使在 STL 之外,它们也非常方便。
Edit: Jerry's answer is better, and more comprehensive.
编辑:杰瑞的回答更好,更全面。