为什么要覆盖 operator()?

在 Boost Signals 库中,他们正在重载 () 运算符.

In the Boost Signals library, they are overloading the () operator.

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

Is this a convention in C++? For callbacks, etc.?

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

I have seen this in code of a co-worker (who happens to be a big Boost fan). Of all the Boost goodness out there, this has only led to confusion for me.

对此超载的原因有任何见解吗?

Any insight as to the reason for this overload?

推荐答案

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

One of the primary goal when overloading operator() is to create a functor. A functor acts just like a function, but it has the advantages that it is stateful, meaning it can keep data reflecting its state between calls.

这是一个简单的函子示例:

Here is a simple functor example :

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 允许您对范围的每个元素应用操作.它可以实现如下:

Functors are heavily used with generic programming. Many STL algorithms are written in a very general way, so that you can plug-in your own function/functor into the algorithm. For example, the algorithm std::for_each allows you to apply an operation on each element of a range. It could be implemented something like that :

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

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

You see that this algorithm is very generic since it is parametrized by a function. By using the operator(), this function lets you use either a functor or a function pointer. Here's an example showing both possibilities :

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() 重载的问题,是的,这是可能的.只要您遵守方法重载的基本规则(例如,仅在返回类型上重载是不可能的),您就可以完美地编写具有多个括号运算符的函子.


Concerning your question about operator() overloading, well yes it is possible. You can perfectly write a functor that has several parentheses operator, as long as you respect the basic rules of method overloading (e.g. overloading only on the return type is not possible).

相关文章