Какой случай лучше? - PullRequest
       31

Какой случай лучше?

7 голосов
/ 14 декабря 2010

У меня есть список MyClass:

struct MyClass {
     bool is_old_result(int lifetime);
};
std::list<MyClass> results;
int lifetime = 50; // or something else

Какой случай удаления лучше ( C ++ дизайн и производительность ):

results.remove_if(
    std::bind2nd(std::mem_fun_ref(&MyClass::is_old_result), lifetime));

или

results.remove_if(boost::bind(&MyClass::is_old_result, _1, lifetime));

или

struct RemoveFunctor {
   RemoveFunctor (int lifetime) : lifetime(lifetime) {}
   bool operator()(const MyClass & m) { return m.is_old_result(lifetime); }
private:
   int lifetime;
};
results.remove_if(RemoveFunctor(lifetime));

а почему?

P.S. Пожалуйста, без лямбда-функции и без C ++ 0x.

Ответы [ 2 ]

12 голосов
/ 14 декабря 2010

С точки зрения дизайна, тот, кто использует bind, безусловно, самый ясный. (сопровождается явным объектом функции). Зачем? Succinct.

С точки зрения производительности, объект функции должен быть непобедим (все может быть легко проанализировано и встроено). В зависимости от того, как компилятор оптимизирует, тот, который использует bind, может соответствовать ему (вызов is_old_result может быть или не быть через указатель, в зависимости от анализа компилятора).

3 голосов
/ 14 декабря 2010

При более подходящих именах, таких как «IsOldResult» или «ResultOlderThan», я бы сказал, что окончательное решение будет наиболее читабельным, поскольку именно оно больше всего подходит для прозы:

results.remove_if(ResultOlderThan(lifetime));

Однако я бы, вероятно, пошел бы и написал функтор только в том случае, если алгоритм, который он представлял, работал в нескольких контекстах. Мне кажется, что написание 5-строчного класса, который физически удаляется из одного однострочного сайта вызовов, чересчур расточительно.

В противном случае опция boost :: bind имеет мой голос, поскольку между ним и std :: bind2nd (как минимум, _1 и std :: mem_fun_ref соответственно) меньше всего пуха. Кроме того, boost :: bind работает в большинстве случаев, например, в случае, когда вы не привязываете только одну переменную функции, имеющую только два параметра.

...