35

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?

αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71
Scotty
  • 2,480
  • 2
  • 16
  • 20

1 Answers1

54

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.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
Luc Danton
  • 34,649
  • 6
  • 70
  • 114
  • 2
    `std::not1` and `std::not2` still expect those "adaptable" typedefs. – Cubbi Jul 27 '12 at 03:46
  • @Cubbi: Are they the only parts of C++11 that still do? – Scotty Jul 27 '12 at 05:56
  • 1
    @Scotty as far as I've seen, yes, the only non-deprecated parts. And there are some 25 ways to create functors with those typedefs, from `std::function` and `std::mem_fn` to `std::ref` and `std::map::value_comp`. – Cubbi Jul 27 '12 at 14:55