我有一个仿函数,我想与sort()一起使用,有问题的容器有
类型std::list<std::pair<unsigned, unsigned>>
此容器是在GameBoard类函数之一中初始化的临时容器。
仿函数有声明
bool GameBoard::SortMoveList(std::pair<unsigned, unsigned> left,
std::pair<unsigned, unsigned> right)
当我使用仿函数时,我得到编译错误,如下所示:
moveList.sort(&GameBoard::SortMoveList);
错误:
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\list(1324): error C2064: term does not evaluate to a function taking 2 arguments
1> C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\list(1394) : see reference to function template instantiation 'void std::list<_Ty>::merge<_Pr3>(std::list<_Ty> &,_Pr3)' being compiled
1> with
1> [
1> _Ty=std::pair<unsigned int,unsigned int>,
1> _Pr3=bool (__thiscall GameBoard::* )(std::pair<unsigned int,unsigned int>,std::pair<unsigned int,unsigned int>)
1> ]
1> GameBoard.cpp(341) : see reference to function template instantiation 'void std::list<_Ty>::sort<bool(__thiscall GameBoard::* )(std::pair<_Ty1,_Ty2>,std::pair<_Ty1,_Ty2>)>(_Pr3)' being compiled
1> with
1> [
1> _Ty=std::pair<unsigned int,unsigned int>,
1> _Ty1=unsigned int,
1> _Ty2=unsigned int,
1> _Pr3=bool (__thiscall GameBoard::* )(std::pair<unsigned int,unsigned int>,std::pair<unsigned int,unsigned int>)
1> ]
有什么想法在这里出错吗? 仿函数需要访问类的私有数据,所以我把它作为成员fn。如果它不是成员fn,它编译好。我该如何解决这个问题?
由于
答案 0 :(得分:2)
您不能以这种方式使用成员函数,因为sort()没有需要调用它的对象的概念。正如您在MSVC10中一样,最简单的解决方案是lambda。
std::sort(..., [&, this] -> bool (std::pair<unsigned, unsigned> left, std::pair<unsigned, unsigned> right) {
return this->SortMoveList(left, right);
});
答案 1 :(得分:2)
仿函数是一个对象,其行为类似于函数。
这意味着您需要定义一个定义operator()
的类示例:
class GameBoardMoveListSorter
{
bool operator()(std::pair<unsigned, unsigned> const& left,
std::pair<unsigned, unsigned> const& right) const
{
return left.first < right.first; // or whatever your strict weak ordering is.
}
};
/// STUFF
moveList.sort(GameBoardMoveListSorter());
其他人的评论请:
我虽然新标准允许内部类访问封闭类私有成员。但刚刚重新阅读标准似乎不是我所看到的措辞(编译器的行为似乎允许访问(虽然我知道这方面的一致性一直很弱)。)
与成员函数一样,嵌套类中定义的友元函数(11.4)位于该类的词法范围内;它遵循与名称绑定相同的规则作为该类的静态成员函数(9.4),但它对封闭类的成员没有特殊的访问权限。
基于手册的上述部分。内部类必须是友元类才能访问外部类的私有成员。
请注意。与java不同,内部类和外部类之间没有隐含的父关系。因此,内部类必须具有对外部类对象的显式引用才能访问其成员。
#include <memory>
class Chess
{
private:
int board[8][8];
class GameBoardMoveListSorter
{
GameBoardMoveListSorter(Chess& p)
: parent(p)
{}
bool operator()(std::pair<unsigned, unsigned> const& left,
std::pair<unsigned, unsigned> const& right) const
{
int val = parent.board[0][0] + parent.board[7][7];
return left.first + val < right.first - val; // or whatever your strict weak ordering is.
}
Chess& parent;
};
// I believe that it must be a friend to access private members.
friend class GameBoardMoveListSorter;
public:
void makeMove()
{
std::list<std::pair<unsigned, unsigned> > moveList(/*Generate Moves*/);
moveList.sort(GameBoardMoveListSorter(*this));
// Do something with the move list.
}
};
答案 2 :(得分:1)
您可以将此功能与boost :: bind一起使用。
moveList.sort(boost::bind(&GameBoard::SortMoveList, this, _1, _2 ) );
如果你的实现不需要“this”那么(即它没有咨询任何类成员来计算比较),那么不要把它变成类成员函数(甚至不是静态函数)。
注意:对于boost::bind
,您可以替换为std::bind
或std::tr1::bind
,具体取决于VC10附带的内容,这应该有效。