На самом деле операторы <<
и >>
являются операторами сдвига битов;строго говоря, использование их для ввода / вывода уже неправильно.Однако такое неправильное использование примерно столько же, сколько и сама перегрузка операторов, и в настоящее время наиболее часто их используют операции ввода-вывода, поэтому они широко рассматриваются как операторы ввода / вывода ввода-вывода.Я почти уверен, что если бы не было прецедента iostreams, никто бы не использовал эти операторы для ввода-вывода (особенно с C ++ 11, в котором есть переменные шаблоны, решая основную проблему, которая с помощью этих операторов решалась для iostreams, внамного чище способ).С другой стороны, с языковой точки зрения, перегруженные operator<<
и operator>>
могут означать то, что вы хотите, чтобы они имели в виду.
Таким образом, вопрос сводится к тому, что было бы приемлемым использование этих операторов.Для этого, я думаю, нужно различать два случая: во-первых, новые перегрузки, работающие с классами iostream, и, во-вторых, новые перегрузки, работающие с другими классами, возможно, предназначенные для работы подобно iostreams.
Давайте рассмотрим первые новые операторы назанятия iostream.Позвольте мне начать с наблюдения, что все классы iostream - это форматирование (и обратный процесс, который можно назвать «деформатированием»; «лексирование») ИМХО здесь не совсем подходит, поскольку экстракторы не определяют тип, но только попытайтесь интерпретировать данные в соответствии с указанным типом).Классы, ответственные за фактический ввод / вывод необработанных данных, являются streambufs.Однако обратите внимание, что правильный двоичный файл - это , а не файл, в который вы просто записываете внутренние необработанные данные.Как и текстовый файл (на самом деле даже больше), двоичный файл должен иметь четко определенную кодировку содержащихся в нем данных.Особенно, если файлы должны быть прочитаны в разных системах.Поэтому концепция форматированного вывода имеет смысл также для двоичных файлов;отличается только форматирование (например, запись предварительно определенного числа байтов с самым старшим первым для целочисленного значения).
Сами iostreams являются классами, которые предназначены для работы с текстовыми файлами, то естьна файлах, содержание которых интерпретируется как текстовое представление данных.Многие встроенные функции оптимизированы для этого и могут вызывать проблемы при использовании в двоичных файлах.Очевидным примером является то, что по умолчанию пробелы пропускаются перед попыткой ввода.Для двоичного файла это было бы явно неправильным поведением.Кроме того, использование локалей не имеет смысла для двоичных файлов (хотя можно утверждать, что может существовать «двоичная локаль», но я не думаю, что локали, определенные для iostreams, обеспечивают подходящий интерфейс для этого).Поэтому я бы сказал, что написание двоичного operator<<
или operator>>
для классов iostream было бы неправильным.
Другой случай, когда вы определяете отдельный класс для двоичного ввода / вывода (возможно, для повторного использования слоя streambuf для выполненияфактический ввод / вывод).Поскольку сейчас мы говорим о разных классах, приведенная выше аргументация больше не применяется.Таким образом, теперь возникает вопрос: должны ли operator<<
и operator>>
на вводе / выводе рассматриваться как «операторы вставки / извлечения текста» или, в более общем смысле, как «операторы вставки / извлечения отформатированных данных»?Стандартные классы используют их только для текста, но тогда вообще не существует стандартных классов для вставки / извлечения двоичного ввода-вывода, поэтому стандартное использование не может различить их.
Лично я бы сказал, что двоичныйвставка / извлечение достаточно близки к текстовой вставке / извлечению, что такое использование оправдано.Обратите внимание, что вы также можете создавать значимые двоичные манипуляторы ввода / вывода, например, bigendian
, littleendian
и intwidth(n)
, чтобы определить формат, в котором должны быть выведены целые числа.
Помимо этого, есть также использование этих операторов для вещей, которые на самом деле не являются вводом-выводом (и где вы даже не думаете об использовании слоя streambuf), например, чтение или вставка в контейнер.На мой взгляд, это уже является неправильным использованием операторов, потому что там данные не переводятся в другой формат или из него.Он просто хранится в контейнере.