Создание собственных манипуляторов без аргументов
Написание манипуляторов, не использующих аргументы, не требует ни производных классов, ни использования сложных макросов. Предположим, что принтеру требуется пара <ESC>[ для ввода полужирного режима. Эту пару символов можно вставить прямо в поток:
cout << "regular " << '\033' << '[' << "boldface" << endl;
Или можно определить манипулятор bold
, который вставляет символы:
ostream& bold(ostream& os) {
return os << '\033' << '[';
}
cout << "regular " << bold << "boldface" << endl;
Глобально определенная функция bold
принимает ссылку ostream
в качестве аргумента и возвращает ссылку ostream
. Это не функция-член или друг, так как она не нуждается в доступе к элементам частного класса. Функция bold
подключается к потоку, так как оператор потока <<
перегружен, чтобы принимать этот тип функции. Для этого используется следующее объявление:
_Myt& operator<<(ios_base& (__cdecl *_Pfn)(ios_base&))
{
// call ios_base manipulator
(*_Pfn)(*(ios_base *)this);
return (*this);
}
Эту функцию можно использовать для расширения других перегруженных операторов. В этом случае это случайно, что bold
вставляет символы в поток. Функция вызывается, когда она вставляется в поток, не обязательно при печати смежных символов. Таким образом печать может быть отложена из-за буферизации потока.