【问题标题】:What case is better?什么情况比较好?
【发布时间】:2010-12-14 14:39:53
【问题描述】:

我有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. 请不要使用 lambda 函数,也不要使用 C++0x。

【问题讨论】:

    标签: c++ performance stl language-design functor


    【解决方案1】:

    在设计方面,使用bind的绝对是最清晰的。 (后跟显式函数对象)。为什么?简洁。

    在性能方面,函数对象应该是无与伦比的(一切都可以轻松分析和内联)。根据编译器的优化方式,使用bind 的那个可能会匹配它(对is_old_result 的调用可能是也可能不是通过指针,具体取决于编译器的分析)。

    【讨论】:

    • 我也同意,绑定语法是最容易阅读的。如果性能是次要问题,请在此处使用 bind。
    • 我也同意,并且我会补充一点,除非/直到您分析并确定此语句是性能瓶颈,否则性能应该是次要问题。
    • boost::bind 方法还有助于相当容易地转换到 C++0x,如果提问者希望这样做的话。 (我知道提问者说没有 C++0x,但我认为这仍然是一个有效的观点。)
    【解决方案2】:

    使用更合适的命名,例如“IsOldResult”或“ResultOlderThan”,我会说最终的解决方案将是最易读的,因为它是最适合散文的解决方案:

    results.remove_if(ResultOlderThan(lifetime));
    

    但是,如果函子表示的算法出现在多个上下文中,我可能只会去编写函子。对我来说,编写一个从其单个单行调用站点物理移除的 5 行类似乎过于浪费。

    否则, boost::bind 选项有我的投票权,因为它与 std::bind2nd (分别为 _1 和 std::mem_fun_ref )之间的额外绒毛最少。此外,boost::bind 通常适用于更多情况,例如您不只绑定只有两个参数的函数的一个变量的情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 2010-09-22
      • 2011-02-21
      • 2013-01-02
      • 2021-06-30
      • 2013-11-08
      • 2014-10-06
      相关资源
      最近更新 更多