Я записал тонны operator<<(std::ostream &, const T &)
функции - они невероятно полезны.
Я никогда не писал operator>>(std::istream &, T &)
функция в реальном коде или даже используемый операторы извлечения для встроенных типов (хорошо, возможно, для std::string
). Они подходят только для коротких примеров программы и учебников? operator>>
неудавшаяся функция C++?
Вопросы спросили о безопасно перегружающихся потоковых операторах. То, что интересно, - то, если кто-либо делает это на практике.
Даже для чего-то простого как чтение входа из файла в C++ я не могу предложить использовать operator>>
. Слишком трудно написать код, который устойчив в обнаружении и ошибках из-за неправильного обращения во входе (или я не знаю как).
Если Вы не соглашаетесь, покажите хороший пример использования operator>>
- возможно, путем ответа на тот последний вопрос я связался с.
Спасибо за ответы все, много хороших мнений. Ответ Manuel заставил меня пересмотреть свое нежелание к использованию op>>
таким образом, я признал что один.
Я думаю, что операторы извлечения потока могут быть очень полезны в сочетании с такими алгоритмами STL, как std :: copy
и с std :: istream_iterator
класс.
Прочтите этот ответ , чтобы понять, о чем я говорю.
Значения чаще печатаются, чем читаются, поэтому оператор<<
используется чаще, чем оператор>>
. Тем не менее, если вы хотите прочитать значения, operator>>
будет полезен.
То, что вы должны проверять ошибки, не является специфичным для operator>>
, очевидно, что и любой другой способ чтения значений должен каким-то образом обнаруживать недопустимый ввод.
Да, я использую оператор >> (хотя и не так часто, как оператор <<). Это очень полезно для разбора пользовательских типов на соответствующие объекты и, следовательно, централизации синтаксического анализа и необходимой обработки ошибок. Это также очень полезно для анализа строкового представления перечислимого типа.
Например, рассмотрим нумерованный тип, представляющий фрукт. Вы можете использовать оператор >> для анализа строки (например, «яблоко», «банан» и т. Д.), Чтобы получить правильное значение перечисления.
std::istream &operator>>(std::istream &is, Fruit &fruit)
{
std::string str;
is >> str;
if (str == "apple")
fruit = APPLE;
else if (str == "banana")
fruit = BANANA;
// other fruits
else
is.setstate(std::ios::failbit);
return is;
}
Обратите внимание на использование метода setstate в потоке istream для установки состояния отказа потока при обнаружении неизвестной строки. Используя этот оператор, вы можете проверить состояние отказа потока следующим образом:
Fruit fruit;
std::cin >> fruit;
if (std::cin.fail())
std::cout << "Error: Unknown Fruit!" << std::endl;
Я никогда не пишу их, и довольно редко использую "встроенные". Операторы извлечения довольно бесполезны для чтения интерактивного пользовательского ввода, потому что поток слишком легко испортить. Написание собственной процедуры разбора почти всегда проще и надежнее. Что касается сериализации, если я хочу сохранить что-то в виде текста, я делаю это в стандартном промышленном формате, таком как XML, для чтения которого операторы извлечения явно не подходят. В противном случае я сохраняю данные в базе данных или в двоичном файле, которые опять же плохо подходят для использования экстракторами".
operator>>
полезен при преобразовании чисел в текстовом виде во внутреннее представление.
Он также может быть полезен при загрузке данных для объектов. В отличие от scanf
, который не может быть перегружен для различных типов, объекты могут перегружать operator>>
. Таким образом, это обеспечивает большее сокрытие данных при загрузке объектов, внутреннее представление не нужно знать, чтобы прочитать данные в объект.
Оператор >> по сути является десериализацией. По моему ограниченному и анекдотическому опыту, большая часть сериализации / десериализации в C ++ реализована на более низком уровне, чем потоковая библиотека. Это не обязательно должно быть реализовано на более низком уровне - это обычно так.
Реализация пользовательской десериализации не всегда является тривиальной проблемой, но вы, вероятно, столкнетесь с теми же проблемами, даже если вы не реализуете ее с синтаксисом извлечения потока.
Вот пример использования оператора извлечения потока, который хоть немного полезен: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html # faq-39.2
В этой ограниченной области кажется, что правильное использование довольно просто.
Я активно использовал operator<< для сборки списков инструкций сортировки, полей в представлениях базы данных и т.д. в моем OOFILE API базы данных.
По какой-то причине большое количество пользователей сочли интуитивно понятным использование оператора>> для добавления поля сортировки, которое было обратной сортировкой. Я не знаю, кто предложил эту идею, но она понравилась достаточному количеству людей, и ее включили в API.
например:
dbSorter arcSort; // declare a sorter
arcSort << reverse(Date) << FileName; // "normal" way to specify two sort fields
arcSort >> Date << FileName; // shorthand way that evolved to specify
Мы также использовали обычный оператор operator>> для разбора целой dbTable из потока.