Иногда требуется нестандартный манипулятор. Программирование манипуляторов без аргументов не представляет особой сложности. Для этого надо просто написать функцию, которая получает и возвращает ссылку на поток. Например, пусть нам нужен манипулятор, вставляющий в поток символ табуляции (листинг 14.11).
Листинг 14.11. Манипулятор без аргументов
std::ostream& tab(std::ostream& os) { return (os << '\f ); }
Использовать такой манипулятор так же просто, как и стандартный: cout << 12 << tab << 25 << endl;
Обычно манипуляторы без аргументов пишутся для объединения свойств нескольких стандартных манипуляторов. Например, ранее мы рассматривали следующий оператор вывода:
cout << setfillC-') << setw(10) << hex << internal << val << endl:
Этот оператор можно записать значительно короче, если объединить все использованные в нем манипуляторы в одной функции (листинг 14.12).
Листинг 14.12. «Объединяющий» манипулятор
ostream& setfix(ostream& os) { os.width(10): os.fi11():
os.setf(ios::internal, ios::adjustfield);
os.setf(ios::hex, ios::basefield);
return os;
}
В результате вывод в cout той же переменной val в том же формате записывается значительно короче:
cout << setfix << val << endl:
Написать манипулятор с аргументами несколько сложнее. Собственно, для создания манипулятора, совместимого по интерфейсу со стандартными манипуляторами, нужно разобраться в стандартном механизме реализации. Однако вместо этого можно просто написать некоторый класс, для которого, как обычно, определить функцию operator<<. Джерри Шварц1 назвал такие классы эффекторами (см. также [12]). Например, пусть нам требуется выводить целые значения в двоичном виде. Напишем класс binary (листинг 14.13). |