Создание собственных манипуляторов без аргументов

Написание манипуляторов, не использующих аргументы, не требует ни производных классов, ни использования сложных макросов. Предположим, что принтеру требуется пара <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 вставляет символы в поток. Функция вызывается, когда она вставляется в поток, не обязательно при печати смежных символов. Таким образом печать может быть отложена из-за буферизации потока.

См. также

Потоки вывода