Ответ 1
mem_fn
намного меньше, чем bind
, поэтому, если вам нужны только функции mem_fn
, для этого требуется гораздо меньше кода.
Я просматриваю библиотеки Boost, которые были включены в технический отчет 1 С++, и пытаюсь понять, что каждый делает.
Я только что закончил пример для boost::mem_fn
, и теперь мне интересно, в чем смысл использовать его вместо лучшего boost::bind
. Насколько я понимаю, оба из них возвращают объект функции, указывающий на функцию-член. Я считаю, что mem_fn
настолько ограничен, что я не могу найти сценарий, где его использование будет лучше, чем bind
.
Я что-то упустил? Есть ли случай, когда bind не может заменить mem_fn?
mem_fn
намного меньше, чем bind
, поэтому, если вам нужны только функции mem_fn
, для этого требуется гораздо меньше кода.
mem_fn
меньше и быстрее, чем bind
. Попробуйте следующую программу с вашим любимым компилятором и сравните:
Вы можете сравнить производительность bind
по сравнению с mem_fn
, изменив значение 1 на 0 в строке #if
.
#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;
}
Результаты будут разными, но в моей текущей версии версия исполняемого файла mem_fn
меньше 220 байт и работает примерно в два раза быстрее, чем версия bind
.
И в качестве бонусной функции mem_fn
не требует, чтобы вы не добавляли std::placeholders::_1
, как bind does
(от боли от неясной ошибки шаблона компилятора).
Итак, предпочитайте mem_fn
, когда можете.
Ну, привязка зависит от mem_fun, так что вы идете. Как и почему я уйду для вас, потому что, хотя интересно, у меня нет времени для расследования прямо сейчас (привязка сложна).
boost::lambda
имеет аналогичное перекрытие функциональности с двумя упомянутыми вами. Я думаю, что они все развивались с похожими намерениями примерно в одно и то же время с разными подходами, что приводило к проблемам с путаницей и несовместимостью. Было бы неплохо, если бы все они слились под одним зонтиком lambda
.
Итак, нет, нет всеобъемлющего дизайна, который требует, чтобы обе библиотеки сосуществовали.