Подтвердить что ты не робот

Кто-нибудь действительно использует операторы извлечения потока?

Я написал тонны функций operator<<(std::ostream &, const T &) - они невероятно полезны.

Я никогда не писал функцию operator>>(std::istream &, T &) в реальном коде или даже использовал операторы извлечения для встроенных типов (ОК, возможно, для std::string). Являются ли они подходящими только для коротких примеров программ и учебников? Является ли operator>> неудачной функцией С++?

Были заданы вопросы о безопасном перегрузке операторов потоков. Что мне интересно, если кто-то делает это на практике.

Даже для чего-то простого, такого как чтение ввода из файла в С++, я не могу предложить использовать operator>>. Слишком сложно написать код, который является надежным при обнаружении и обработке ошибок во вводе (или я не знаю, как это сделать).

Если вы не согласны, пожалуйста, покажите хороший пример использования operator>> - возможно, отвечая на этот последний вопрос, с которым я связан.


Wrapup: Спасибо за ответы всем, много хороших мнений. Ответ Мануэля заставил меня пересмотреть мое нежелание использовать op>>, поэтому я принял это.
4b9b3361

Ответ 1

Я думаю, что операторы выделения потоков могут быть очень полезны в сочетании с алгоритмами STL, такими как std::copy и с классом std::istream_iterator.

Прочитайте этот ответ, чтобы узнать, о чем я говорю.

Ответ 2

Да, я использую оператор → (хотя не так часто, как оператор < <). Это очень полезно для анализа пользовательских типов в их соответствующих объектах и, следовательно, для централизации анализа и необходимой обработки ошибок. Это также очень полезно для синтаксического анализа строкового представления перечислимого типа.

Например, рассмотрим перечисляемый тип, представляющий плод. Вы можете использовать оператор → для анализа строки (например, "яблоко", "банан" и т.д.), Чтобы получить правильное значение перечисления.

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;

Ответ 3

Значения чаще печатаются, чем чтение, поэтому operator<< используется чаще, чем operator>>. Тем не менее, если вы хотите читать значения, полезно использовать operator>>.

То, что вы должны проверять наличие ошибок, не относится к operator>>, очевидно, что любой другой способ чтения значений должен каким-то образом обнаруживать недопустимый ввод.

Ответ 4

Я никогда их не пишу и редко использую "встроенные". Операторы извлечения довольно бесполезны для чтения интерактивных пользовательских вводных данных, потому что слишком непросто для потока работать плохо. Написание пользовательской процедуры синтаксического анализа почти всегда проще и надежнее. И когда дело доходит до сериализации, если я хочу что-то сохранить как текст, я делаю это в стандартном формате, таком как XML, который операторы извлечения явно не подходят для чтения. В противном случае я храню данные в базе данных или в двоичном файле, что еще раз плохо подходит для использования с экстракторами.

Ответ 5

operator>> полезен при преобразовании чисел в текстовой форме во внутреннее представление.

Он также может быть полезен при загрузке данных для объектов. В отличие от scanf, которые не могут быть перегружены для разных типов, объекты могут перегружать operator>>. Таким образом, он обеспечивает больше данных, скрывающихся для загрузки объектов, внутреннее представление не обязательно должно быть известно для чтения данных в объект.

Ответ 6

Оператор → - это в основном десериализация. В моем ограниченном и анекдотическом опыте большинство сериализации/десериализации в С++ реализовано на более низком уровне, чем библиотека потока. Он не должен быть реализован на более низком уровне - он обычно есть.

Реализация пользовательской десериализации не всегда является тривиальной проблемой, но вы, вероятно, столкнетесь с теми же проблемами, даже если вы не реализуете ее с синтаксисом извлечения потока.

Здесь используется чистое использование оператора извлечения потока, который, по крайней мере, минимально полезен: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

В этой ограниченной области, кажется, правильное использование довольно просто.

Ответ 7

Я сильно использовал оператор < для сборки списков инструкций сортировки, полей в представлениях базы данных и т.д. в моем API OOFILE.

По какой-то причине большое количество пользователей посчитало интуитивным использование оператора → в добавить поле сортировки, которое было обратным видом. Я не знаю, кто предложил это в первую очередь, но он обратился к достаточно людям, которые сделали это в 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 

Мы также использовали обычное использование оператора → для синтаксического анализа всего dbTable из потока.