Я недавно обнаружил, что в C++ можно перегрузить оператор "вызова функции" странным способом, которым необходимо записать две пар круглой скобки, чтобы сделать так:
class A {
int n;
public:
void operator ()() const;
};
И затем используйте его этот путь:
A a;
a();
Когда это полезно?
Это можно использовать для создания «функторов» , объектов, которые действуют как функции:
class Multiplier {
public:
Multiplier(int m): multiplier(m) {}
int operator()(int x) { return multiplier * x; }
private:
int multiplier;
};
Multiplier m(5);
cout << m(4) << endl;
Выше отпечатаны 20
. В указанной выше статье в Википедии приведены более существенные примеры.
Если вы создаете класс, который инкапсулирует указатель на функцию, это может сделать использование более очевидным.
Использование operator () не более чем синтаксический выигрыш, пока вы не начнете использовать шаблоны. Но при использовании шаблонов вы можете одинаково относиться к реальным функциям и функторам (классам, действующим как функции).
class scaled_sine
{
explicit scaled_sine( float _m ) : m(_m) {}
float operator()(float x) const { return sin(m*x); }
float m;
};
template<typename T>
float evaluate_at( float x, const T& fn )
{
return fn(x);
}
evaluate_at( 1.0, cos );
evaluate_at( 1.0, scaled_sine(3.0) );
Алгоритм, реализованный с использованием шаблона, не заботится о том, является ли вызываемый объект функцией или функтором, он заботится о синтаксисе. Либо стандартные (например, for_each ()), либо свои собственные. А функторы могут иметь состояние и делать все, что угодно, когда они вызываются. Функции могут иметь состояние только со статической локальной переменной или глобальными переменными.