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:
- The size of the resulting executable and
- 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.
精彩评论