Чтение онлайн

на главную - закладки

Жанры

Эффективное использование STL
Шрифт:

Помимо побочных эффектов между

for_each
и
accumulate
существуют два основных различия. Во-первых, само название
accumulate
ассоциируется с вычислением сводного значения по интервалу, а название
for_each
скорее предполагает выполнение некой операции с каждым элементом интервала. Алгоритм
for_each
может использоваться дя вычисления сводной величины, но такие решения по наглядности уступают
accumulate
.

Во-вторых, accumulate непосредственно возвращает вычисленное значение,

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

Ниже приведен предыдущий пример, в котором вместо accumulate используется

for_each
:

struct Point{…}; // См. ранее

class PointAverage;

public unary_function<Point, void>{ // См. совет 40

public:

 PointAverage: xSum(0), ySum(0), numPoints(0) {}

 void operator(const Point& p) {

++numPoints;

xSum += p.x;

ySum += p.y;

 }

 Point result const {

return Point(xSum/numPoints, ySum/numPoints);

 }

private:

 size t numPoints;

 double xSum;

 double ySum;

};

list<Point> lp;

Point avg = for_each(lp.begin, lp.end, PointAverage).result;

Лично я предпочитаю обобщать интервальные данные при помощи

accumulate
, поскольку мне кажется, что этот алгоритм наиболее четко передает суть происходящего, однако
foreach
тоже работает, а вопрос побочных эффектов для
for_each
не так принципиален, как для
accumulate
. Словом, для обобщения интервальных данных могут использоваться оба алгоритма; выберите тот, который вам лучше подойдет.

Возможно, вас интересует, почему у

for_each
параметр-функция может иметь побочные эффекты, а у
accumulate
— не может? Представьте, я бы тоже хотел это знать. Что ж, дорогой читатель, некоторые тайны остаются за пределами наших познаний. Чем
accumulate
принципиально отличается от
for_each
? Пока я еще не слышал убедительного ответа на этот вопрос.

Функции, функторы и классы функций

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

find_if
, конструкции
for_each
и
transform
без них теряют смысл, а адаптеры типа
not1
и
bind2nd
активно создают их.

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

ptr_fun
,
mem_fun
и
mem_fun_ref
. При желании начните с совета 41, но пожалуйста, не останавливайтесь на этом. Когда вы поймете, для чего нужны эти функции, материал остальных советов поможет вам наладить правильное взаимодействие ваших функторов с ними и с STL в целом.

Совет 38. Проектируйте классы функторов для передачи по значению

Ни C, ни C++ не позволяют передавать функции в качестве параметров других функций. Вместо этого разрешается передавать указатели на функции. Например, объявление стандартной библиотечной функции

qsort
выглядит следующим образом:

void qsort(void *base, size_t nmemb, size_t size,

 int (*cmpfcn)(const void*, const void*));

В совете 46 объясняется, почему вместо функции

qsort
обычно рекомендуется использовать алгоритм
sort
, но дело не в этом. Нас сейчас интересует объявление параметра
cmpfcn
функции
qsort
. При внимательном анализе становится ясно, что аргумент
cmpcfn
, который является указателем на функцию, копируется (то есть передается по значению) из точки вызова в функцию
qsort
. Данный пример поясняет правило, соблюдаемое стандартными библиотеками C и C++, — указатели на функции должны передаваться по значению.

Объекты функций STL создавались по образцу указателей на функции, поэтому в STL также действует правило, согласно которому объекты функций передаются по значению (то есть копируются). Вероятно, это правило лучше всего демонстрирует приведенное в Стандарте объявление алгоритма

for_each
, который получает и передает по значению объекты функций:

template<class InputIterator, class Function>

Function // Возврат по значению

for_each(InputIterator first, InputIterator last,

 Function f);// Передача по значению

Честно говоря, передача по значению не гарантирована полностью, поскольку вызывающая сторона может явно задать типы параметров в точке вызова. Например, в следующем фрагменте

for_each
получает и возвращает функторы по ссылке:

class DoSomething:

 public unary_function<int, void>{ // Базовый класс описан

Поделиться:
Популярные книги

Эпоха Опустошителя. Том II

Павлов Вел
2. Вечное Ристалище
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Эпоха Опустошителя. Том II

Жена со скидкой, или Случайный брак

Ардова Алиса
Любовные романы:
любовно-фантастические романы
8.15
рейтинг книги
Жена со скидкой, или Случайный брак

Запечатанный во тьме. Том 1. Тысячи лет кача

NikL
1. Хроники Арнея
Фантастика:
уся
эпическая фантастика
фэнтези
5.00
рейтинг книги
Запечатанный во тьме. Том 1. Тысячи лет кача

Виктор Глухов агент Ада. Компиляция. Книги 1-15

Сухинин Владимир Александрович
Виктор Глухов агент Ада
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
попаданцы
5.00
рейтинг книги
Виктор Глухов агент Ада. Компиляция. Книги 1-15

Древесный маг Орловского княжества 3

Павлов Игорь Васильевич
3. Орловское княжество
Фантастика:
аниме
сказочная фантастика
фэнтези
попаданцы
гаремник
5.00
рейтинг книги
Древесный маг Орловского княжества 3

Адвокат Империи 14

Карелин Сергей Витальевич
14. Адвокат империи
Фантастика:
городское фэнтези
аниме
попаданцы
5.00
рейтинг книги
Адвокат Империи 14

Страж Кодекса. Книга IV

Романов Илья Николаевич
4. КО: Страж Кодекса
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Страж Кодекса. Книга IV

Я еще не бог. Книга XXXV

Дрейк Сириус
35. Дорогой барон!
Фантастика:
аниме
попаданцы
5.00
рейтинг книги
Я еще не бог. Книга XXXV

Я спас СССР! том 2

Вязовский Алексей
2. Я спас СССР
Фантастика:
альтернативная история
5.62
рейтинг книги
Я спас СССР! том 2

Кодекс Охотника XXXI

Винокуров Юрий
31. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника XXXI

Наномашины, первоклашка! Том 4

Новиков Николай Васильевич
4. Чего смотришь? Иди книгу читай
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Наномашины, первоклашка! Том 4

Громовая поступь. Трилогия

Мазуров Дмитрий
Громовая поступь
Фантастика:
фэнтези
рпг
4.50
рейтинг книги
Громовая поступь. Трилогия

Снайпер

Поселягин Владимир Геннадьевич
3. Жнец
Фантастика:
боевая фантастика
попаданцы
5.60
рейтинг книги
Снайпер

Кодекс Крови. Книга ХVI

Борзых М.
16. РОС: Кодекс Крови
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга ХVI