std::mem_fun vs std::mem_fn

Scotty picture Scotty · Jul 27, 2012 · Viewed 9.6k times · Source

What is the difference between std::mem_fun and std::mem_fn? Why is the naming so confusing?

Boost's documentation says that std::mem_fn can replace std::mem_fun in most cases. So in what situation would you still use std::mem_fun?

Answer

Luc Danton picture Luc Danton · Jul 27, 2012

std::mem_fun is deprecated. std::mem_fn can do everything it does, and it does it more conveniently. The relation between the two is the same as the relation between std::bind1st/std::bind2nd and the C++11 std::bind. Both std::mem_fn and std::bind were developed and mastered after std::bind1st and std::mem_fun were made into the C++98 Standard. So that means we had to wait until C++11 to properly replace the old stuff with the superior alternatives.

For instance, std::mem_fun can only deal with member functions that take one or no argument. std::mem_fn is variadic and can deal with members that take any number of arguments.

You also need to pick between std::mem_fun and std::mem_fun_ref depending on whether you want to deal with pointers or references for the class object (respectively). std::mem_fn alone can deal with either, and even provides support for smart pointers.

The documentation of boost::mem_fn explains when to use std::mem_fun, and put simply that's when you need to operate with code that expects std::mem_fun, or that expects adaptable functors (which is an obsolete notion* from C++03). For those cases you wouldn't be able to plug in std::mem_fn either, so there you have it: you would use std::mem_fun for legacy.

*: I mean by that that new code shouldn't rely on the C++03 protocol of having e.g. result_type member types (it's more customary to use the new traits like std::result_of) -- the new facilities like std::bind/std::mem_fn do in fact provide those members if they would have been present in equivalent C++03 code. I leave it to you to figure out whether you should update old code that relies on adaptable functors with std::mem_fn by relying on this behaviour.