开发者

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?


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.


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.


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).


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜