Кто-нибудь на самом деле использует операторы извлечения потока? - PullRequest
21 голосов
/ 22 февраля 2010

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

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

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

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

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


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

Ответы [ 7 ]

8 голосов
/ 22 февраля 2010

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

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

6 голосов
/ 22 февраля 2010

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

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

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 голосов
/ 22 февраля 2010

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

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

2 голосов
/ 22 февраля 2010

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

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

2 голосов
/ 22 февраля 2010

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

1 голос
/ 22 февраля 2010

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

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

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

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

0 голосов
/ 22 февраля 2010

Я интенсивно использовал оператор << для составления списков команд сортировки, полей в представлениях базы данных и т. Д. В моем <a href="http://www.oofile.com.au/oofile_ref/htmlwin/" rel="nofollow noreferrer"> 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 

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

...