Бьерн Страуструп - Язык программирования С++. Главы 8-10 - Вывод
ОГЛАВЛЕНИЕ
10.2 ВЫВОД
Строгую типовуюиединообразнуюработу как со встроенными,так и спользовательскими типамиможнообеспечить,если использовать единственное перегруженное имя функции для различных операций вывода.Например:
put(cerr,"x = "); // cerr - выходной поток ошибокТип аргумента определяет какую функцию надо вызывать в каждом случае. Такой подход применяется в нескольких языках, однако, это слишком длинная запись. За счет перегрузки операции << , чтобы она означала
put(cerr,x);
put(cerr,'\n');
"вывести" ("put to"), можно получить более простую запись и разрешить программисту выводить в одном операторе последовательность объектов, например так:
cerr << "x = " << x << '\n';Здесь cerr обозначает стандартный поток ошибок. Так, если х типа int со значением 123, то приведенный оператор выдаст
x = 123и еще символ конца строки в стандартный поток ошибок. Аналогично, если х имеет пользовательский тип complex со значением (1,2.4), то указанный оператор выдаст
x = (1,2.4)в поток cerr. Такой подход легко использовать пока x такого типа, для которого определена операция <<,а пользователь может просто доопределить << для новых типов.
Мы использовали операцию вывода, чтобы избежать многословности, неизбежной, если применять функцию вывода. Но почему именно символ << ? Невозможно изобрести новую лексему (см. 7.2).Кандидатом для ввода и вывода была операция присваивания, но большинство людей предпочитает, чтобы операции ввода и вывода были различны. Более того, порядок выполнения операции = неподходящий, так cout=a=b означает cout=(a=b). Пробовали использовать операции < и >, но к ним так крепко привязано понятие "меньше чем" и "больше чем", что операции ввода-вывода с ними во всех практически случаях не поддавались прочтению.
Операции << и >> похоже не создают таких проблем. Они асиметричны, что позволяет приписывать им смысл "в" и "из". Они не относятся к числу наиболее часто используемых операций над встроенными типами, а приоритет << достаточно низкий, чтобы писать арифметические выражения в качестве операнда без скобок:
cout << "a*b+c=" << a*b+c << '\n';Скобки нужны, если выражение содержит операции с более низким приоритетом:
cout << "a^b|c=" << (a^b|c) << '\n';Операцию сдвига влево можно использовать в операции вывода, но, конечно, она должна быть в скобках:
cout << "a<<b=" << (a<<b) << '\n';