What's the point of using boost::mem_fn if we have boost::bind?

I'm having a look at the Boost libraries that were included in C++'s Technical Report 1 and trying to understand what each does.

I've just finished running an example for boost::mem_fn and now I'm wondering what's the point of using it instead of the better boost::bind. As far as I understand, both of them return a function object pointing to a member function. I find mem_fn so limited that I can't find a scenario where using it would be better than bind.

Am I missing something? Is there any case in which bind cannot replace mem_fn?

Upvotes: 14

Views: 3980

Answers (4)

Jeff Wofford
Jeff Wofford

Reputation: 11587

mem_fn is smaller and faster than bind. Try the following program with your favorite compiler and compare:

  1. The size of the resulting executable and
  2. The number of seconds reported as being spent.

You can compare the performance of bind versus mem_fn by changing the 1 to a 0 in the #if line.

#include <iostream>
#include <functional>
#include <chrono>

struct Foo
{
    void bar() {}
};

int main(int argc, const char * argv[])
{   
#if 1
    auto bound = std::bind( &Foo::bar, std::placeholders::_1 );
#else
    auto bound = std::mem_fn( &Foo::bar );
#endif
    Foo foo;
    auto start = std::chrono::high_resolution_clock::now();
    for( size_t i = 0; i < 100000000; ++i )
    {
        bound( foo );
    }
    auto end = std::chrono::high_resolution_clock::now();
    auto delta = std::chrono::duration_cast< std::chrono::duration< double >>( end - start );
    std::cout << "seconds = " << delta.count() << std::endl;
    return 0;
}

Results will vary, but on my current system the mem_fn version of the executable is 220 bytes smaller and runs about twice as fast as the bind version.

And as a bonus feature, mem_fn doesn't require you to remember to add std::placeholders::_1 like bind does (on pain of an obscure templated compiler error).

So, prefer mem_fn when you can.

Upvotes: 6

Jeff Hardy
Jeff Hardy

Reputation: 7662

mem_fn is much smaller than bind, so if you only need the functionality of mem_fn it's a lot less code to pull in.

Upvotes: 7

John
John

Reputation: 59

boost::lambda has a similar overlap of functionality with the two you mentioned. I think they all sort of evolved with similar intent, about the same time, with different approaches, resulting in confusion and incompatibility issues. It'd be nice if they all merged under one lambda umbrella.

So, no, there is no overarching design that calls for both libraries to co-exist.

Upvotes: 1

Edward Strange
Edward Strange

Reputation: 40897

Well, bind depends on mem_fun so there you go. How and why I'll leave for you to discover since although interesting, I haven't got the time to investigate right now (bind is complicated).

Upvotes: 2

Related Questions