Читаем Thinking In C++. Volume 2: Practical Programming полностью

Since iterators are identical to pointers in all essential ways, you can write the algorithms in the standard library in such a way as to allow both pointer and iterator arguments. For this reason, the implementation of copy( ) looks more like the following code.

template

void copy(Iterator begin, Iterator end, Iterator dest) {

  while (begin != end)

    *begin++ = *dest++;

}

Whichever argument type you use in the call, copy( ) assumes it properly implements the indirection and increment operators. If it doesn’t, you’ll get a compile-time error.

<p>Predicates</p>

At times, you might want to copy only a well-defined subset of one sequence to another, such as only those elements that satisfy a certain condition. To achieve this flexibility, many algorithms have alternate calling sequences that allow you to supply a predicate, which is simply a function that returns a Boolean value based on some criterion. Suppose, for example, that you only want to extract from a sequence of integers those numbers that are less than or equal to 15. A version of copy( ) called remove_copy_if( ) can do the job, like this:.

//: C06:CopyInts2.cpp

// Ignores ints that satisfy a predicate

#include

#include

#include

using namespace std;

// You supply this predicate

bool gt15(int x) {

  return 15 < x;

}

int main() {

  int a[] = {10, 20, 30};

  const size_t SIZE = sizeof a / sizeof a[0];

  int b[SIZE];

  int* endb = remove_copy_if(a, a+SIZE, b, gt15);

  int* beginb = b;

  while (beginb != endb)

    cout << *beginb++ << endl; // Prints 10 only

} ///:~.

The remove_copy_if( ) function template takes the usual range-delimiting pointers, followed by a predicate of your choosing. The predicate must be a pointer to function[79] that takes a single argument of the same type as the elements in the sequence, and it must return a bool. In this case, the function gt15 returns true if its argument is greater than 15. The remove_copy_if( ) algorithm applies gt15( ) to each element in the input sequence and ignores those elements when writing to the output sequence.

The following program illustrates yet another variation of the copy algorithm.

//: C06:CopyStrings2.cpp

// Replaces strings that satisfy a predicate

#include

#include

#include

#include

using namespace std;

// The predicate

bool contains_e(const string& s) {

  return s.find('e') != string::npos;

}

int main() {

  string a[] = {"read", "my", "lips"};

  const size_t SIZE = sizeof a / sizeof a[0];

  string b[SIZE];

  string* endb =

    replace_copy_if(a, a + SIZE, b, contains_e,

     string("kiss"));

  string* beginb = b;

  while (beginb != endb)

    cout << *beginb++ << endl;

} ///:~.

Instead of just ignoring elements that don’t satisfy the predicate, replace_copy_if( ) substitutes a fixed value for such elements when populating the output sequence. The output in this case is

kiss

my

lips

because the original occurrence of "read", the only input string containing the letter e, is replaced by the word "kiss", as specified in the last argument in the call to replace_copy_if( ).

The replace_if( ) algorithm changes the original sequence in place, instead of writing to a separate output sequence, as the following program shows.

//: C06:ReplaceStrings.cpp

// Replaces strings in-place

#include

#include

#include

#include

using namespace std;

bool contains_e(const string& s) {

  return s.find('e') != string::npos;

}

int main() {

  string a[] = {"read", "my", "lips"};

  const size_t SIZE = sizeof a / sizeof a[0];

  replace_if(a, a + SIZE, contains_e, string("kiss"));

  string* p = a;

  while (p != a + SIZE)

    cout << *p++ << endl;

} ///:~

<p>Stream iterators</p>

Like any good software library, the Standard C++ Library attempts to provide convenient ways to automate common tasks. We mentioned in the beginning of this chapter that you can use generic algorithms in place of looping constructs. So far, however, our examples have still used an explicit loop to print their output. Since printing output is one of the most common tasks, you would hope for a way to automate that too.

That’s where stream iterators come in. A stream iterator allows you to use a stream as either an input or an output sequence. To eliminate the output loop in the CopyInts2.cpp program, for instance, you can do something like the following.

//: C06:CopyInts3.cpp

// Uses an output stream iterator

#include

#include

#include

#include

using namespace std;

bool gt15(int x) {

  return 15 < x;

}

int main() {

  int a[] = {10, 20, 30};

  const size_t SIZE = sizeof a / sizeof a[0];

  remove_copy_if(a, a + SIZE,

  ostream_iterator(cout, "\n"), gt15);

} ///:~.

Перейти на страницу:

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

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

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

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

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

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

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

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