(пример 11.4).

Пример 11.4. Поиск максимального элемента для пользовательских типов

#include <algorithm>

#include <vector>

#include <iostream>

using namespace std;

struct Chessplayer {

 ChessPlayer(const char* name, int rating)

  : name_(name), rating_(rating) { }

 const char* name_;

 int rating_;

};

struct IsWeakerPlayer {

 bool operator()(const ChessPlayer& x, const ChessPlayer& y) {

 return x.rating_ < y.rating_;

};

int main() {

 ChessPlayer kasparov('Garry Kasparov', 2805);

 ChessPlayer anand('Viswanathan Anand', 2788);

 ChessPlayer topalov('Veselin Topalov', 2788);

 vector<ChessPlayer> v;

 v.push_back(kasparov);

 v.push_back(anand);

 v.push_hack(topalov);

 cout << 'the best player is ';

 cout << max_element(v.begin(), v.end(), IsWeakerPlayer())->name_;

 cout << endl;

}

Программа примера 11.4 выдает следующий результат.

the best player is Garry Kasparov (лучший игрок - Гарри Каспаров)

Функторы

Многие STL-алгоритмы в качестве параметров используют определенные пользователем объекты- функции и указатели на функции. И те и другие называются функторами (functors). Иногда в литературе термин «объект-функция» используется как синоним термина «функтор», однако я использую термин «объект-функция» для обозначения только экземпляров класса или структур, которые перегружают operator(). Какой из двух типов функторов лучше использовать? В большинстве случаев объект-функция более эффективен, потому что большинство компиляторов могут легко его реализовать в виде встроенной функции.

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

Наконец, объекты-функции могут определяться внутри другой функции или класса. Указатели на функции приходится объявлять в области видимости пространства имен.

В примере 11.4 я показал, как в функции max_element можно использовать пользовательский предикат. Этот предикат является объектом-функцией IsWeakerPlayer.

Альтернативой пользовательскому предикату, показанному в примере 11.4, является перегрузка оператора operator< для структуры ChessPlayer. Это хорошо работает в определенных случаях, но предполагает, что самой важной является сортировка игроков по рейтингу. Может оказаться, что более распространенной является сортировка по именам. Поскольку в данном случае выбор метода сортировки может быть произвольным, я предпочитаю не определять оператор operator<.

11.3. Вычисление суммы и среднего значения элементов контейнера

Проблема

Требуется вычислить сумму и среднее значение чисел, содержащихся в контейнере.

Решение

Для расчета суммы можно использовать функцию accumulate из заголовочного файла <numeric> и затем разделить ее на количество элементов, получая среднее значение. Пример 11.5 демонстрирует, как это можно сделать, используя вектор.

Пример 11.5. Вычисление суммы и среднего значения элементов контейнера

#include <numeric>

#include <iostream>

#include <vector>

using namespace std;

int main() {

 vector<int> v;

 v.push_back(1);

 v.push_back(2);

 v.push_back(3);

 v.push_back(4);

 int sum = accumulate(v.begin(), v.end(), 0);

 double mean = double(sum) / v.size();

 cout << 'sum = ' << sum << endl;

 cout << 'count = ' << v.size() << endl;

 cout << 'mean = ' << mean << endl;

}

Программа примера 11.5 выдает следующий результат.

sum = 10

count = 4

mean = 2.5

Обсуждение

Как правило, функция accumulate обеспечивает самый эффективный и самый простой способ вычисления суммы всех элементов, содержащихся в контейнере.

Несмотря на то что данный рецепт имеет относительно простое решение, не так уж просто написать

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату