Читаем Программирование полностью

Если мы хотим сравнивать элемент с произвольным значением v, то должны как-то сделать это значение неявным аргументом предиката алгоритма find_if(). Мы могли бы попробовать (выбрав в качестве удобного имени идентификатор v_val).

double v_val; // значение, с которым предикат larger_than_v()

              // сравнивает свой аргумент

bool larger_than_v(double x) { return x>v_val; }

void f(list& v,int x)

{

  v_val = 31; // устанавливаем переменную v_val равной 31,

              // для следующего вызова предиката larger_than_v

  list::iterator p = find_if(v.begin(),v.end(),

                                     larger_than_v);

  if (p!=v.end()) { /* мы нашли значение, превышающее 31 */ }

    v_val = x; // устанавливаем переменную v_val равной x

               // для следующего вызова предиката larger_than_v

  list::iterator q = find_if(v.begin(), v.end(),

                                     larger_than_v);

  if (q!=v.end()) { /* мы нашли значение, превышающее x*/ }

    // ...

}

  Какая гадость! Мы убеждены, что люди, написавшие такую программу, в конце концов получат по заслугам, но мы заранее сочувствуем пользователям и любому человеку, который столкнется с этим кодом. Повторим: должен быть более удобный способ!

ПОПРОБУЙТЕ

Почему такое использование переменной v вызывает у нас такое отвращение? Назовите по крайней мере три способа, которые приведут к непонятным ошибкам. Назовите три приложения, в которых такие программы особенно недопустимы. 

<p id="AutBody_Root394"><strong>21.4. Объекты-функции</strong></p>

Итак, мы хотим передавать предикат алгоритму find_if() и чтобы этот предикат сравнивал элементы со значением, которое мы зададим как его аргумент. В частности, мы хотим написать примерно такой код:

void f(list& v, int x)

{

  list::iterator p = find_if(v.begin(), v.end(),

  Larger_than(31));

  if (p!=v.end()) { /* мы нашли число, превышающее 31 */ }

    list::iterator q = find_if(v.begin(), v.end(),

  Larger_than(x));

  if (q!=v.end()) { /* мы нашли число, превышающее x */ }

    // ...

}

Очевидно, что функция Larger_than должна удовлетворять двум условиям.

• Ее можно вызывать как предикат, например pred(*first).

• Она может хранить значение, например 31 или x, передаваемое при вызове.

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

class Larger_than {

  int v;

public:

  Larger_than(int vv) : v(vv) { } // хранит аргумент

  bool operator()(int x) const { return x>v; } // сравнение

};

Следует отметить, что это определение представляет собой именно то, что мы требовали от предиката. Теперь осталось понять, как это работает. Написав выражение Larger_than(31), мы (очевидно) создаем объект класса Larger_than, хранящий число 31 в члене v. Рассмотрим пример.

find_if(v.begin(),v.end(),Larger_than(31))

Здесь мы передаем объект Larger_than(31) алгоритму find_if() как параметр с именем pred. Для каждого элемента v алгоритм find_if() осуществляет вызов

pred(*first)

Это активизирует оператор вызова функции, т.е. функцию-член operator(), для объекта-функции с аргументом *first. В результате происходит сравнение значения элемента, т.е. *first, с числом 31.

Мы видим, что вызов функции можно рассматривать как результат работы оператора (), аналогично любому другому оператору. Оператор () называют также оператором вызова функции (function call operator) или прикладным оператором (application operator). Итак, оператор () в выражении pred(*first) эквивалентен оператору Larger_than::operator(), точно так же, как оператор [] в выражении v[i] эквивалентен оператору vector::operator[].

<p id="AutBody_Root395"><strong>21.4.1. Абстрактная точка зрения на функции-объекты</strong></p>
Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных