什么时候无状态类函子代替交流风格功能?

Mic*_*nen 6 c++ operator-overloading functor

我发现在这么喜欢仿函数的一些很好的例子一个,所有的说服力的例子似乎在定义类的使用状态operator().

我在一本书中找到了一个例子来定义没有状态的函数调用操作符,我不禁觉得这是一个尴尬的用法,而且一个普通的样式函数指针,会比operator()在各方面使用更好 - 更少的代码,更少的变量(你必须实例化比较器),它可能由于实例化而更有效,并且没有意义或封装的损失(因为它只是一个函数).

我知道std::sort让你在operator()类和函数之间进行选择,但由于上述逻辑,我总是只使用这些函数.

为什么选择课程的原因是什么?

这是一个例子(释义):

class Point2D {
   //.. accessors, constructors
   int x,y;
};
class HorizComp {
public:
   bool operator()(const Point2D& p, const Point2D& q) const
   { return p.getX() < q.getX(); }
};

class VertComp {
public:
   bool operator()(const Point2D& p, const Point2D& q) const
   { return p.getY() < q.getY(); }
};

template <typename E, typename C>
void printSmaller(const E& p, const E& q, const C& isLess) {
   cout << (isLess(p, q) ? p : q) << endl; // print the smaller of p and q
}
//...
// usage in some function:
Point2D p(1.2, 3.2), q(1.5, 9.2);
HorizComp horizComp;
VertComp vorizComp;
printSmaller(p, q, horizComp);
printSmaller(p, q, vorizComp);
Run Code Online (Sandbox Code Playgroud)

And*_*ron 8

典型的原因是当你这样做时:

bool less_than(const Point&, const Point&);
// ...
std::sort(..., &less_than);
Run Code Online (Sandbox Code Playgroud)

谓词的模板参数如下:

bool(const Point&,const Point&)
Run Code Online (Sandbox Code Playgroud)

由于sort函数接收函数指针,因此编译器更难以在内部内联谓词std::sort().这是因为你可以有另一个功能

bool greater_than(const Point&, const Point&);
Run Code Online (Sandbox Code Playgroud)

它具有完全相同的类型,意味着std::sort()在两个谓词之间共享实例.(记住,我说它使内联更难,而不是不可能).

相反,当你这样做:

struct less_than {
    bool operator()(const Point&, const Point&) const;
};
// ...
std::sort(..., less_than());


struct greater_than {
    bool operator()(const Point&, const Point&) const;
};
// ...
std::sort(..., greater_than());
Run Code Online (Sandbox Code Playgroud)

编译器std::sort()为每个谓词生成唯一的模板实例化,从而更容易内联谓词的定义.


Jer*_*fin 6

一个原因是运行时效率.如果将指针传递给函数,编译器必须非常聪明才能为内联函数生成代码.通过定义对象operator()使得编译器更容易产生内联代码.特别是对于像分类这样的东西,这可以相当大地提高速度.

在C++ 11中,使用类的另一个原因是为了方便起见 - 您可以使用lambda表达式来定义类.