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

    typedef T2 second_type;

    T1 first;

    T2 second;

    pair();      // конструктор по умолчанию

    pair(const T1& x,const T2& y);

                 // копирующие операции:

    template pair(const pair& p);

};


template

  pair make_pair(T1 x, T2 y) { return pair(x,y); }


Функция make_pair() упрощает использование пар. Например, рассмотрим схему функции, возвращающей значение и индикатор ошибки.


pair my_fct(double d)

{

  errno = 0; // очищаем индикатор ошибок в стиле языка C

             // выполняем много вычислений, связанных с переменной d,

             // и вычисляем x

  error_indicator ee = errno;

  errno = 0; // очищаем индикатор ошибок в стиле языка C

  return make_pair(x,ee);

}


Этот пример является полезной идиомой. Его можно использовать следующим образом:


pair res = my_fct(123.456);

if (res.second==0) {

  // используем res.first

}

else {

  // Ой: ошибка

}

Б.7. Потоки ввода-вывода

Библиотека потоков ввода-вывода содержит средства форматированного и неформатированного буферизованного ввода-вывода текста и числовых значений.

Определения потоков ввода-вывода находятся в заголовках , и т.п. (см. раздел Б.1.1).

Объект класса ostream преобразовывает объекты, имеющие тип, в поток символов (байтов).



Объект класса istream преобразовывает поток символов (байтов) в объекты, имеющие тип.



Объект класса iostream — это поток, который может действовать и как объект класса istream, и как объект класса ostream. Буфера, изображенные на диаграмме, являются потоковыми буферами (streambuf). Если читателям потребуется перейти от потоков класса iostream к новым видам устройств, файлов или памяти, они смогут найти их описание в профессиональных учебниках.

Существуют три стандартных потока.



Б.7.1. Иерархия потоков ввода-вывода

Поток istream можно связать с устройством ввода (например, клавиатурой), файлом или объектом класса string. Аналогично поток ostream можно связать с устройством вывода (например, текстовым окном), файлом или объектом класса string. Потоки ввода-вывода образуют иерархию классов.



Поток можно открыть либо с помощью конструктора, либо вызова функции open().



Для файловых потоков имя файлов представляет собой строку в стиле языка С.

Открыть файл можно в одном из режимов, приведенных ниже.



В каждом из этих режимов открытие файла может зависеть от операционной системы и ее возможностей учесть требование программиста открыть файл именно так, а не иначе. В результате поток может не оказаться в состоянии good(). Рассмотрим пример.


void my_code(ostream& os); // функция my_code может использовать

                           // любой поток вывода

ostringstream os;          // буква "o" означает "для вывода"

ofstream of("my_file");

if (!of) error("невозможно открыть 'my_file' для записи");

my_code(os); // используется объект класса string

my_code(of); // используется файл


См. раздел 11.3.

Б.7.2. Обработка ошибок

Поток iostream может пребывать в одном из четырех состояний.



Используя функцию s.exceptions(), программист может потребовать, чтобы поток iostream сгенерировал исключение, если из состояния good() он перешел в другое состояние (см. раздел 10.6).

Любая операция, в результате которой поток не находится в состоянии good(), не имеет никакого эффекта; такая ситуация называется “no op”.

Объект класса iostream можно использовать как условие. В данном случае условие является истинным (успех), если поток iostream находится в состоянии good(). Это обстоятельство стало основой для распространенной идиомы, предназначенной для считывания потока значений.


X x; // "буфер ввода" для хранения одного значения типа X

while (cin>>x) {

  // какие-то действия с объектом x

}

// мы окажемся в этой точке, если оператор >> не сможет прочитать

// очередной объект класса X из потока cin

Б.7.3. Операции ввода

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже