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

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

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

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

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

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


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

7 ответов

Решение

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

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

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

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

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;

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

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

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

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

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

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

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

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

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

Я интенсивно использовал operator<< для сборки списков инструкций сортировки, полей в представлениях базы данных и т. Д. В моем 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 из потока.

Другие вопросы по тегам