将功能实现为仿函数的优缺点

Pros and Cons of implementing functionality as functor

我正在与一位同事讨论只有一个 public 方法的简单 class 的 API。我最初去了:

class CalculateSomething
{
public:
  void operator()(const SomeObject &obj) const;

private:
  // ...
}

然而,我的同事反对使用 operator() 并希望简单地将方法命名为 'calculate' 为了清楚起见。 虽然我觉得这个论点没有说服力,但它让我想到了利弊。

优势运算符()

缺点运算符()

我很惊讶地发现我对此的搜索并没有带来太多结果,因为我认为这是很常见的情况(一个 class,一个责任)。因此,我真的很想听听其他人对此的看法。

如果 lambda 确实 不是一个选项,您的选择应该取决于对象承担的工作范围...以及您的编码约定或风格。您可以决定显式(参见 的回答),如果该方法相对不熟悉并且需要状态,这是一件好事,但是

让我们从标准库中获取简单的用例...

  • std::hash:这是一个只做一项工作的函数对象,而且据说做得很好,对此没有争议
  • 还有很多...包括std::less及其分类

你看到的所有这些的共同点是它们是 动词...在我看来,如果你的 class 与你发布的片段完全一样, CalculateSomething 对我来说意味着一个动作,所以我总是可以将它实例化为 CalculateSomething()(my_object...).

正如您引用的那样,它在使用 STL 算法本身和许多其他 C++ 库时非常方便。 如果你采用你同事的方法,你可能不得不使用 std::binds 和 lambda,因为你想要 'adapt' 一个接口。

示例:

class CalculateSomething
{
    public:
         void operator()(const SomeObject &obj) const;
    private:
         // ...
}

class CalculateNothing
{
    public:
         void calculate(const SomeObject &obj) const;
    private:
         // ...
}

示例用法是:

std::for_each(container.begin(), container.end(), CalculateSomething());

反对

std::for_each(container.begin(), container.end(), [ c = CalculateNothing()](auto x) { c.calculate(x); });

我想我更喜欢前者。

嗯,这也是我的 5 美分。

首先,如果可能的话,我会简单地使用 lambda 或自由函数。您确定,您需要 class 来满足您的需求吗?

无论如何,假设 class 是必需的。

  1. 我不太喜欢使用 operator()。也许还有其他评论。
  2. 可能最好将其重命名为“SomethingCalculator” - 它不是一个对象吗?
  3. 你可以添加一个方法,比如“DoWork”、“Calculate”等等。

这将使它更加明确。

UPD. 以上所有内容仍有争议,但我真正相信的是,添加足够的代码内文档将带来真正的不同,与方法名称无关.