为什么要覆盖 operator()?

新手上路,请多包涵

Boost Signals 库中,它们重载了 () 运算符。

这是 C++ 中的约定吗?对于回调等?

我在一位同事的代码中看到了这一点(他恰好是 Boost 的忠实粉丝)。在所有 Boost 的优点中,这只会让我感到困惑。

关于这种超载的原因有什么见解吗?

原文由 JeffV 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 833
2 个回答

重载 operator() 时的主要目标之一是创建一个仿函数。仿函数的行为就像一个函数,但它的优点是它是有状态的,这意味着它可以在调用之间保持数据反映其状态。

这是一个简单的仿函数示例:

 struct Accumulator
{
    int counter = 0;
    int operator()(int i) { return counter += i; }
}
...
Accumulator acc;
cout << acc(10) << endl; //prints "10"
cout << acc(20) << endl; //prints "30"

函子在泛型编程中大量使用。许多 STL 算法都以非常通用的方式编写,因此您可以将自己的函数/函子插入到算法中。例如,算法 std::for_each 允许您对范围的每个元素应用操作。它可以像这样实现:

 template <typename InputIterator, typename Functor>
void for_each(InputIterator first, InputIterator last, Functor f)
{
    while (first != last) f(*first++);
}

您会看到该算法非常通用,因为它是由函数参数化的。通过使用 operator(),此函数允许您使用仿函数或函数指针。这是一个显示两种可能性的示例:

 void print(int i) { std::cout << i << std::endl; }
...
std::vector<int> vec;
// Fill vec

// Using a functor
Accumulator acc;
std::for_each(vec.begin(), vec.end(), acc);
// acc.counter contains the sum of all elements of the vector

// Using a function pointer
std::for_each(vec.begin(), vec.end(), print); // prints all elements


关于您关于 operator() 重载的问题,是的,这是可能的。只要您遵守方法重载的基本规则(例如,仅在返回类型上重载是不可能的),您就可以完美地编写一个具有多个括号运算符的仿函数。

原文由 Luc Touraille 发布,翻译遵循 CC BY-SA 3.0 许可协议

许多人回答说它是一个函子,但没有说明函子比普通旧函数更好的一个重要原因。

答案是函子可以有状态。考虑一个求和函数——它需要保持一个运行总计。

 class Sum
{
public:
    Sum() : m_total(0)
    {
    }
    void operator()(int value)
    {
        m_total += value;
    }
    int m_total;
};

原文由 Mark Ransom 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题