Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between std::function and std::mem_fn

I am having trouble figuring out the difference between the two function wrappers std::function and std::mem_fn. From the description, it seems to me that std::function does everything std::mem_fn does and more. In which instance would one use std::mem_fn over std::function?

like image 827
Vicks Avatar asked May 07 '15 16:05

Vicks


2 Answers

You can't really compare std::function with std::mem_fn. The former is a class template whose type you specify, and the latter is a function template with unspecified return type. There really isn't a situation in which you'd actually consider one versus the other.

A better comparison might be between mem_fn and std::bind. There, for the specific use-case of a pointer-to-member, mem_fn is going to a lot less verbose if all you want to do is pass-through all the arguments. Given this simple type:

struct A { 
    int x;
    int getX() { return x; }
    int add(int y) { return x+y; }
};

A a{2};

How would you make a functor that just calls getX() on a given A?

auto get1 = std::mem_fn(&A::getX);
auto get2 = std::bind(&A::getX, _1);

get1(a); // yields 2
get2(a); // same

And takes an additional argument for add?

auto add1 = std::mem_fn(&A::add);
auto add2 = std::bind(&A::add, _1, _2);

add1(a, 5); // yields 7
add2(a, 5); // same

So mem_fn is more concise in this case. However, if we wanted to bind a specific argument, say call add(5) on a given A, you can only do that with bind:

auto add_5 = std::bind(&A::add, _1, 5);
add_5(a); // yields 7 

Ultimately, no comparison between function and mem_fn, but there are times to prefer mem_fn to bind.

like image 145
Barry Avatar answered Nov 01 '22 13:11

Barry


The wrapper returned by std::mem_fn is extremely lightweight; it's a thin wrapper around a pointer to member.

std::function uses type erasure, which is a lot more heavyweight.

like image 28
T.C. Avatar answered Nov 01 '22 14:11

T.C.