这两种方法中哪一种更好,为什么?

方法1:

void fun(int i) {
  //do stuff
}

...
for_each(a.begin(), a.end(), fun);

方法2:

class functor {
public:
  void operator()(int i);
};

...
for_each(a.begin(), a.end(), functor());

编辑:应该用这种方式制定,在什么情况下上述方法之一优于另一种?

非常感谢!

有帮助吗?

解决方案

Functors可以(并且)简单地内联–这不是针对常规函数指针。

因此,仿函数具有真正的性能优势,在紧密循环中可能是巨大的。此外,仿函数通常更易于组合,特别是使用STL更好: std :: bind x 不适用于函数指针,例如。

我讨厌它们如何使代码混乱,但是考虑到所有优点,我更喜欢它们而不是函数指针。

其他提示

为了清除对编译器可以内联的误解,一个足够好的编译器可以内联函数指针。它可以更容易地内联函数对象,因为有更多的静态信息可用。例如,指向不带参数并返回bool的函数的指针是bool(*)()类型,而仿函数有一个显式类型,即仿函数,模板实例化可以静态调用仿函数运算符,而不是而不必通过函数指针调用。

但实际上,主要是为编译器提供足够的信息以便有效地进行优化。

例如,Visual C ++ 2008,给出以下代码并进行完全优化:

#include "stdafx.h"
#include <algorithm>

const char print_me[]= "hello!";

class print_functor
{
public:
    void operator()(char c)
    {
        printf("%c", c);
    }
};

void print_function(char c)
{
    printf("%c", c);
}

int _tmain(int argc, _TCHAR* argv[])
{
    std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_functor());
    printf("\n");

    std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_function);

    return 0;
}

完全内联 std :: for_each 。顺便说一句,在PC上,第一个for_each有一个不必要的 lea ecx,[ecx]

函数对象相对于函数指针的一大优点是,您可以更容易地在函数对象构造中绑定一些参数。

可能会这样做的仿函数的一个例子是

  class multiplyBy
  {
  private:
      int m_whatToMultiplyBy;
  public:
      multiplyBy(int whatToMultiplyBy) : 
          m_whatToMultiplyBy(whatToMultiplyBy)
      {
      }

      void operator()(int& i)
      {
          i = m_whatToMultiplyBy * i;
      }
  }


  ...

  // double the array
  for_each(a.begin(), a.end(), multiplyBy(2));

这种“绑定”是指“绑定”。可以使用 boost :: bind boost :: function 如果提升是你可以使用。

我的观点 - #1更好,因为它更简单。

仅仅因为某物可以成为一个物体,并不意味着它应该是一个物体。我确信有些情况下仿函数有意义,但在大多数情况下可能没有必要。

仿函数可以更容易内联,因此它可能是一个因素考虑绩效何时重要。

#1更容易声明函数
而#2的仿函数看起来更像是一个函数调用。

(有时候你不得不对c ++语法感到绝望)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top