Вы пропустили дополнительную пару круглых скобок при объявлении operator()
. Имя функции - operator()
, и ему по-прежнему нужен список параметров после него. Таким образом, он должен выглядеть следующим образом:
int operator()(int a) {return a;}
функциональных объектов (также известные функторы), как это, как правило, используется там, где вы будете использовать указатель на функцию. Однако у них есть то преимущество, что они могут использовать наследование, а также инкапсулировать состояние. Часто хорошо продуманные шаблоны классов или функций могут использовать их почти взаимозаменяемо с указателями функций. Однако хороший оптимизатор обычно может создавать лучший код при использовании объекта шаблона.
Для довольно сложный пример того, как можно использовать функциональные объекты, посмотреть на expression templates.
Вот небольшой, несколько надуманный пример того, как они могут использовать наследование:
struct unary_int_func {
virtual int operator()(int i) = 0;
};
struct negate : public unary_int_func {
int operator()(int i) {return -i;}
};
struct one_plus : public unary_int_func {
int operator()(int i) {return i+1;}
};
void show_it(unary_int_func &op, int v) {
cout << op(v) << endl;
}
В этом случае , мы создаем базовый класс с оператором как чистую виртуальную функцию. Затем мы получаем конкретные классы, которые его реализуют. Код, такой как show_it()
, может затем использовать любой экземпляр класса, полученного из этой базы. Хотя мы могли бы просто использовать указатель на функцию, которая принимает int и возвращает int, это более типично. Код, который использует указатель на функцию будет принимать любой такой указатель функции, в то время как таким образом мы можем определить целую новую иерархию, которая отображает Int к междунар:
struct a_different_base_class {
virtual int operator()(int i) = 0;
};
но экземпляры этого бы не быть взаимозаменяемыми с примерами unary_int_func.
Что касается состояния, рассмотрим бегущую функцию суммы:
struct running_sum : public unary_int_func {
int total;
running_sum() : total(0) {}
int operator()(int i) {return total += i;}
};
int main()
{
running_sum s;
cout << s(1) << endl;
cout << s(2) << endl;
cout << s(3) << endl;
cout << s(4) << endl;
}
Здесь экземпляр running_sum
отслеживает общую. Он будет распечатывать 1, 3, 6 и 10. Указатели на функции не имеют такого способа сохранения состояния между различными вызовами. На странице STL SGI на function objects приведен пример, похожий на мою текущую сумму, но показывает, как вы можете легко применить его к ряду элементов в контейнере.
Я решил эту проблему, но я хотел бы знать, почему функторы используются в C++. Его недостающие фигурные скобки. – brett
@Brett: Функторы? – 2010-09-13 05:33:56
@thyrgle yes Функторы – mousey