Jef*_*ffV 52 c++ boost operator-overloading functor function-call-operator
在Boost Signals库中,它们重载了()运算符.
这是C++中的约定吗?对于回调等?
我在同事的代码中看到了这一点(恰好是Boost的忠实粉丝).在那里的所有Boost善良中,这只会让我感到困惑.
有关这种超载原因的任何见解?
Luc*_*lle 135
重载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"
Run Code Online (Sandbox Code Playgroud)
Functor大量使用泛型编程.许多STL算法都是以非常通用的方式编写的,因此您可以将自己的函数/仿函数插入到算法中.例如,算法std :: for_each允许您对范围的每个元素应用操作.它可以实现类似的东西:
template <typename InputIterator, typename Functor>
void for_each(InputIterator first, InputIterator last, Functor f)
{
while (first != last) f(*first++);
}
Run Code Online (Sandbox Code Playgroud)
您会看到此算法非常通用,因为它是由函数参数化的.通过使用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
Run Code Online (Sandbox Code Playgroud)
关于你关于operator()重载的问题,是的,这是可能的.只要您遵守方法重载的基本规则(例如,不能仅在返回类型上进行重载),您就可以完美地编写具有多个括号运算符的仿函数.
Lod*_*dle 25
它允许类充当函数.我在一个日志类中使用它,其中调用应该是一个函数,但我想要该类的额外好处.
所以这样的事情:
logger.log("Log this message");
Run Code Online (Sandbox Code Playgroud)
变成这样:
logger("Log this message");
Run Code Online (Sandbox Code Playgroud)
函子不是函数,因此不能重载它。
你的同事是正确的,尽管operator()的重载用于创建“函子”——可以像函数一样调用的对象。与期望“类似函数”参数的模板相结合,这可能非常强大,因为对象和函数之间的区别变得模糊。
正如其他发帖者所说:函子比普通函数有一个优势,因为它们可以拥有状态。此状态可用于单次迭代(例如计算容器中所有元素的总和)或多次迭代(例如查找多个容器中满足特定条件的所有元素)。
许多人已经回答它是一个仿函数,没有说明为什么仿函数比普通的旧函数更好的一个重要原因.
答案是仿函数可以有状态.考虑求和函数 - 它需要保持运行总计.
class Sum
{
public:
Sum() : m_total(0)
{
}
void operator()(int value)
{
m_total += value;
}
int m_total;
};
Run Code Online (Sandbox Code Playgroud)