Значение оператора ()? - PullRequest
2 голосов
/ 05 апреля 2011

Что означает оператор () в C ++? Я вижу, что часто используется для «функторов» или функциональных объектов, таких как компараторы. Но тогда как называются такие функции? Это полезно в других ситуациях? А сколько параметров я могу объявить для такого оператора? Например, приемлемо ли следующее?

bool operator() (Foo f, Baz b, Quz q, Oik o) {...}

Ответы [ 5 ]

4 голосов
/ 05 апреля 2011

Допустим, у вас есть класс объекта функции, Func, с определением operator(). Если у вас есть экземпляр этого класса, вы можете просто поместить скобки после выражения, ссылающегося на этот экземпляр:

Func myFunc;
myFunc(); // Calls the operator() member function

В качестве примера из стандартной библиотеки мы можем посмотреть на std::less, который является двоичным объектом функции:

std::less<int> myLess; // Create an instance of the function object
std::cout << myLess(5, 6) << std::endl; // Is 5 less than 6?

Другое распространенное использование для operator() - при создании класса Matrix. Вы можете определить T& Matrix::operator()(int,int) для извлечения элемента из матрицы, например myMatrix(1,2).

Число параметров, которые может принимать operator(), такое же, как и у любой другой функции. Это зависит от реализации, хотя. Рекомендуемое минимальное количество аргументов, которое ваша реализация должна допускать, равно 256 (приведено в Приложении B стандарта).


Подстановка

operator() определяется в стандарте (ISO / IEC 14882: 2003 и раздел; 13.3.1.1.2) следующим образом:

Если первичное выражение E в синтаксисе вызова функции оценивается как объект класса типа "cv T", то набор функций-кандидатов включает, по крайней мере, операторы вызова функции из T. Операторы вызова функции T получены обычным поиском имени operator() в контексте (E).operator().

Перевод: если вы выполняете вызов функции с использованием синтаксиса expression() и выражение перед круглыми скобками оценивает экземпляр класса, то добавьте функцию-член operator() к списку функций-кандидатов, которые могут быть вызваны .

3 голосов
/ 06 апреля 2011

Одна вещь, о которой я не упомянул, заключалась в том, что, хотя в синтаксисе ее вызов очень похож на вызов обычной функции, не являющейся членом (смею сказать, в стиле C).Одно из отличий состоит в том, что, поскольку функтор / объект-функция является экземпляром класса / структуры, он может иметь ассоциированное состояние.

Для функций, не являющихся членами, это обычно может означать либо статические локальные переменные (частолучший или самый полезный способ поддержания состояния) или глобальные переменные (часто нежелательные).Принимая во внимание, что функторы / функциональные объекты хорошо связаны с представлениями C ++ об инкапсуляции, когда в состоянии / данных тесно связаны с функциями, которые над ним работают.

Поучительный пример этого:

//Declaration
struct instructive_example
{
  instructive_example()
: _invocation_count(0) {};

  uint get_invocation_count() const
  { return _invocation_count; }

  void operator()()
  {
    //Do something

    //And/or operate on the state associated with this function object
    //In this case it is a simple increment of _invocation_count
    ++_invocation_count;
  }
private:
  uint _invocation_count;
};

//Instantiation & invocation:
instructive_example eg;

eg();
3 голосов
/ 05 апреля 2011

Если вы реализуете operator() для класса C, то, если c является объектом типа C, вы можете написать c(), который вызывает c.operator()(). Вы можете иметь столько параметров для operator(), сколько хотите.

Один хороший пример того, когда operator() полезен, см. Здесь:

http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10

1 голос
/ 05 апреля 2011

Как и любой перегруженный оператор, operator() - это странное имя функции.Он должен быть функцией-членом класса или структуры, но нет никаких ограничений на его аргументы, кроме обычных правил для всех функций.

Для вычисления выражения x( args ) когда тип x является типом класса, C ++ попытается вызвать x.operator()( args ), где args может быть пустой строкой или любым числомаргументы функции.

0 голосов
/ 05 апреля 2011

Это обычная функция, которая вызывается при применении синтаксиса вызова функции к пользовательскому типу.

Таким образом, он имеет все ограничения и функции обычной функции-члена. Это может быть шаблон, он может принимать столько параметров, сколько вы хотите, ему нужен тип возвращаемого значения, это может быть const и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...