Какой смысл использовать boost :: mem_fn, если у нас есть boost :: bind? - PullRequest
13 голосов
/ 21 июня 2010

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

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

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

Ответы [ 4 ]

6 голосов
/ 22 июня 2010

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

5 голосов
/ 19 января 2013

mem_fn меньше и быстрее, чем bind. Попробуйте следующую программу с вашим любимым компилятором и сравните:

  1. Размер результирующего исполняемого файла и
  2. Количество секунд, сообщенных как потраченные.

Вы можете сравнить производительность 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, когда можете.

2 голосов
/ 22 июня 2010

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

1 голос
/ 22 июня 2010

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

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

...