[mem_fn] Using mem_fn with std::bind2nd

The mem_fn documentation is clear that there may be problems using mem_fn with the standard binders:
mem_fn is not 100% compatible with the standard adaptors, although it comes pretty close. In particular, mem_fn does not return objects of type std::[const_]mem_fun[1][_ref]_t, as the standard adaptors do, and it is not possible to fully describe the type of the first argument using the standard argument_type and first_argument_type nested typedefs. Libraries that need adaptable function objects in order to function might not like mem_fn.
Fair enough. The program below fails to compile with VC8 and g++ 4.1.1, and the VC8 error message (which I find much more readable than the g++ one) suggests that I'm running into the problem mentioned above. However, the program DOES compile using Comeau 4.3.8, and that's what confuses me. Does anybody have any insights into whether this code is supposed to compile? I'm especially interested in any remarks about whether it should compile using std::tr1::mem_fn, should there be any differences between that and boost::mem_fn. Thanks, Scott #include <vector> #include <algorithm> #include <functional> #include "boost/mem_fn.hpp" struct Point { void rotate(int degrees); }; int main() { std::vector<Point> vp; std::for_each(vp.begin(), vp.end(), std::bind2nd(boost::mem_fn(&Point::rotate), 10)); }

Scott Meyers wrote:
The mem_fn documentation is clear that there may be problems using mem_fn with the standard binders:
mem_fn is not 100% compatible with the standard adaptors, although it comes pretty close. In particular, mem_fn does not return objects of type std::[const_]mem_fun[1][_ref]_t, as the standard adaptors do, and it is not possible to fully describe the type of the first argument using the standard argument_type and first_argument_type nested typedefs. Libraries that need adaptable function objects in order to function might not like mem_fn.
Fair enough. The program below fails to compile with VC8 and g++ 4.1.1, and the VC8 error message (which I find much more readable than the g++ one) suggests that I'm running into the problem mentioned above. However, the program DOES compile using Comeau 4.3.8, and that's what confuses me. Does anybody have any insights into whether this code is supposed to compile?
I've no idea how it could work with Comeau 4.3.8. mem_fn(&Point::rotate) defines its ::first_argument_type as Point*. libcomo 3.5's binder2nd takes a first_argument_type: typename _Operation::result_type operator()(const typename _Operation::first_argument_type& __x) const { return op(__x, value); } so it should fail.
I'm especially interested in any remarks about whether it should compile using std::tr1::mem_fn, should there be any differences between that and boost::mem_fn.
tr1::mem_fn is mostly the same. The only difference is that it's required to
derive from std::binary_function
#include <vector> #include <algorithm> #include <functional> #include "boost/mem_fn.hpp"
struct Point { void rotate(int degrees); };
int main() { std::vector<Point> vp;
std::for_each(vp.begin(), vp.end(), std::bind2nd(boost::mem_fn(&Point::rotate), 10)); }
participants (2)
-
Peter Dimov
-
Scott Meyers