将功能实现为函子的优缺点
Pros and Cons of implementing functionality as functor
我正在和一位同事讨论一个只有一个公共方法的简单类的API。我最初选择了:
class CalculateSomething
{
public:
void operator()(const SomeObject &obj) const;
private:
// ...
}
但是,我的同事反对使用 operator((,为了清楚起见,希望简单地将该方法命名为"calculate"。虽然我觉得这个论点没有说服力,但它让我想到了利弊。
优点运算符((
- 该类是精益的,并且有一个明确定义的目的。一旦实例化,它基本上充当一个自由函数。
- 它是一个函子,可以很容易地这样使用(例如STL算法(。
- 当它与范围算法一起使用时,可以直接传递对象,而不是通过函数指针传递,这使编译器能够内联代码。尽管不能保证,但通过函数指针传递它完全抑制了这种可能性。
缺点 运算符((
- 如果不查看类名,则不太清楚该方法的作用。(我个人不同意,因为该类只有一个方法,因此从类名中可以清楚地看出其含义(
- STL 中的大多数函子应该是无状态的。我认为这是阻碍我的主要原因......
我很惊讶地发现我对此的搜索并没有带来太多结果,因为我认为这是一个很常见的场景(一个类,一个责任(。因此,我真的很想听听其他人对此的看法。
如果 lambda 真的不是一种选择,您的选择应该取决于对象承担的工作范围......并导致您的编码约定或样式。你可以决定明确(参见Werolik的答案(,如果该方法相对陌生并且需要状态,这是一件好事,但是
让我们从标准库中获取简单的用例...
- std::hash:这是一个函数对象,可以完成一项工作,并且应该做得很好,对此没有争议
- 还有这么多...包括 std::less 及其分类
你看到的所有这些的共同点是它们是动词......在我看来,如果你的类和你发布的片段一模一样,CalculateSomething
对我来说意味着一个动作,所以我总是可以把它实例化为CalculateSomething()(my_object...)
。
就像你引用的,它在使用 STL 算法本身和许多其他C++库时非常方便。如果你采用同事的方法,你可能不得不求助于使用std::binds和lambdas,因为你想"适应"一个接口。
例:
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 或自由函数。您确定,您需要满足您需求的课程吗?
无论如何,假设该类是必需的。
- 我不太喜欢使用 operator((。也许还有其他评论。
- 可能最好将其重命名为"
SomethingCalculator
' - 它不是一个对象吗? - 然后你可以添加一个方法,比如'
DoWork
'、'Calculate
'或其他什么。
这将使它更加明确。
上。以上所有内容仍然可以争论,但我真正相信的是,添加足够的代码内文档将产生真正的差异,与方法名称无关。
相关文章:
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- 多态性和功能结合
- 带内存和隔离功能的SQLite
- 在CMakeLists.txt的安装功能中使用.cmake文件有什么用
- 类模板的成员功能的定义在单独的TU中完全专业化
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++中获得"静态纯虚拟"功能?
- 两个文件使用彼此的功能-如何解决
- 我应该实现右值推送功能吗?我应该使用std::move吗
- QML按钮点击功能执行顺序
- 无法理解此 return 语句的功能,没有它就会发生运行时错误
- 有没有可能有一个只有ADL才能找到的非好友功能
- 功能样式转换从 'int' 到 'ItemType' 的匹配转换
- 文件系统:复制功能的速度秘诀是什么
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 如何在Directwrite中获得给定字体的可用OpenType功能
- 对可变参数使用声明.如何选择正确的功能
- 询问在设计我的手臂模拟器功能表示格式1
- 功能原型的目的
- 将功能实现为函子的优缺点