Какой смысл использовать boost:: mem_fn, если у нас есть boost:: bind?

Я просматриваю библиотеки Boost, которые были включены в технический отчет 1 С++, и пытаюсь понять, что каждый делает.

Я только что закончил пример для boost::mem_fn, и теперь мне интересно, в чем смысл использовать его вместо лучшего boost::bind. Насколько я понимаю, оба из них возвращают объект функции, указывающий на функцию-член. Я считаю, что mem_fn настолько ограничен, что я не могу найти сценарий, где его использование будет лучше, чем bind.

Я что-то упустил? Есть ли случай, когда bind не может заменить mem_fn?

Ответы

Ответ 1

mem_fn намного меньше, чем bind, поэтому, если вам нужны только функции mem_fn, для этого требуется гораздо меньше кода.

Ответ 2

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, когда можете.

Ответ 3

Ну, привязка зависит от mem_fun, так что вы идете. Как и почему я уйду для вас, потому что, хотя интересно, у меня нет времени для расследования прямо сейчас (привязка сложна).

Ответ 4

boost::lambda имеет аналогичное перекрытие функциональности с двумя упомянутыми вами. Я думаю, что они все развивались с похожими намерениями примерно в одно и то же время с разными подходами, что приводило к проблемам с путаницей и несовместимостью. Было бы неплохо, если бы все они слились под одним зонтиком lambda.

Итак, нет, нет всеобъемлющего дизайна, который требует, чтобы обе библиотеки сосуществовали.