mcostalba wrote:Rein Halbersma wrote:Just let me know if the above compiles.
No sorry it doesn't, there are many errors, the trivial is that you decalred struct is_not_legal_move and then used is_legal_move(), perhasp _I_ have helped creating this when I simplified the original code removing std::not1.
But also with this fixed I still get a good chunk of encrypted error messages
OK Marco, the code below compiles (I checked using out-of-the-box VC++ 2010) but you will not be happy!
Code: Select all
class Position {
//Position() {}; // default ctor will not be generated anyway because of user-defined ctors
//Position(const Position& pos); // std::bind1st generates copy-constructor
public:
// rest as current
...
};
/// generate<MV_LEGAL> computes a complete list of legal moves in the current position
#include <algorithm>
#include <functional>
struct is_legal_move: public std::binary_function<Position, MoveStack, bool>
{
bool operator()(const Position& pos, const MoveStack& cur) const
{
return pos.pl_move_is_legal(cur.move, pos.pinned_pieces(pos.side_to_move()));
}
};
template<>
MoveStack* generate<MV_LEGAL>(const Position& pos, MoveStack* mlist) {
assert(pos.is_ok());
MoveStack* last = pos.in_check() ? generate<MV_EVASION>(pos, mlist)
: generate<MV_NON_EVASION>(pos, mlist);
return std::remove_if(mlist, last, std::not1(std::bind1st(is_legal_move(), pos)));
}
Changes: removed explicit suppression of default ctor. This is unnecessary because the compiler will never generate these for you as long as you define at least one constructor yourself. Even if you define a new position by accident somewhere, your code will not compile.
However, the copy constructor will be automatically generated whenever it is needed, even if you have a self-defined constructor, so that original comment was warranted. But I also removed explicit suppression of the copy constructor because it turns out that std::bindst1 has this nasty code:
Code: Select all
// TEMPLATE FUNCTION bind1st
template<class _Fn2,
class _Ty> inline
binder1st<_Fn2> bind1st(const _Fn2& _Func, const _Ty& _Left)
{ // return a binder1st functor adapter
typename _Fn2::first_argument_type _Val(_Left);
return (_STD binder1st<_Fn2>(_Func, _Val));
}
Here, MSVC++ declares a copy Val_ of _Left just to be able to express the return type of the function object. In reality, this temporary will not be created and fully optimized away, but the compiler first needs the copy constructor to make this happen
Finally I changed is_legal_move to take a const-reference to MoveStack to make the argument deduction on the std::remove_if easier (it got confused what kind of iterator was needed).
So... (deep breath) if you are brave enough to compile and look at the assembly, you will see that no needless copies arise.
Rein