2010-02-22 13 views
21

J'ai écrit des tonnes de fonctions operator<<(std::ostream &, const T &) - elles sont incroyablement utiles.Est-ce que quelqu'un utilise réellement des opérateurs d'extraction de flux?

Je n'ai jamais écrit une fonction operator>>(std::istream &, T &) en code réel ou même utilisé les opérateurs d'extraction pour les types intégrés (OK, peut-être pour std::string). Sont-ils appropriés uniquement pour de courts exemples de programmes et de manuels? Est-ce que operator>> est une fonctionnalité échouée de C++?

Des questions ont été posées à propos de safely overloading stream operators. Ce que je me demande, c'est si quelqu'un le fait en pratique.

Même pour quelque chose de simple comme reading input from a file in C++ Je ne peux pas suggérer d'utiliser operator>>. Il est trop difficile d'écrire du code robuste pour détecter et gérer les erreurs en entrée (ou je ne sais pas comment).

Si vous n'êtes pas d'accord, veuillez montrer un bon exemple d'utilisation de operator>> - peut-être en répondant à la dernière question à laquelle je me suis connecté.


Wrapup: Merci pour les réponses tout le monde, beaucoup de bonnes opinions. La réponse de Manuel m'a fait reconsidérer ma réticence à utiliser op>> alors j'ai accepté celui-là.

+0

Vous devez définir 'op >>' si vous voulez prendre 'lexical_cast'. (http://www.boost.org/doc/libs/1_42_0/libs/conversion/lexical_cast.htm). – kennytm

Répondre

8

Je pense que les opérateurs d'extracteur de flux peuvent être très utiles lorsqu'ils sont combinés avec des algorithmes STL tels que std::copy et avec la classe std::istream_iterator.

Lisez this answer pour voir de quoi je parle.

+0

J'aime cette technique. Je vais devoir l'essayer un jour. – Dan

3

Les valeurs sont plus souvent imprimées que lues, donc operator<< est utilisé plus souvent que operator>>. Néanmoins, si vous voulez lire des valeurs, operator>> est utile.

Que vous deviez vérifier les erreurs n'est pas spécifique à operator>>, évidemment toute autre façon de lire les valeurs devra détecter une entrée invalide d'une manière ou d'une autre.

0

J'ai fait un usage intensif de l'opérateur < < pour assembler des listes d'instructions de tri, de champs dans les vues de base de données, etc. dans mon API de base de données OOFILE.

Pour une raison quelconque, un grand nombre d'utilisateurs ont trouvé intuitif d'utiliser l'opérateur >> à append a sort field which was a reverse sort. Je ne sais pas qui l'a suggéré en premier lieu, mais il a fait appel à suffisamment de gens qu'il a fait dans l'API.

par exemple:

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 

Nous avons également fait une utilisation classique de l'opérateur >> pour analyser un ensemble dbTable d'un cours d'eau.

+0

OK, mais ce n'est pas un extracteur d'istream. J'ai utilisé op >> pour écrire le code de marshaling, où j'avais un contrôle complet sur l'entrée/sortie et toute erreur était fatale. Mais je ne l'ai jamais trouvé utile pour le traitement de texte. – Dan

+0

Je viens de me corriger - OOFILE utilise le modèle conventionnel d'opérateur >> appelant une méthode d'insertion virtuelle pour les tables et les champs. –

1

Opérateur >> est essentiellement la désérialisation. Dans mon expérience limitée et anecdotique, la plus grande partie de la sérialisation/désérialisation en C++ est implémentée à un niveau inférieur à la bibliothèque de flux. Il n'a pas besoin d'être implémenté à un niveau inférieur - c'est généralement le cas.

La mise en œuvre désérialisation personnalisée est pas toujours un problème trivial, mais vous êtes susceptible de se heurter aux mêmes problèmes, même si vous ne mettez pas en œuvre avec la syntaxe d'extraction de flux.

Voici un usage cheezy de l'opérateur d'extraction de flux qui est au moins marginalement utile: http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.2

Dans ce cadre limité, il semble que l'utilisation correcte est assez simple.

+0

C'est un exemple intéressant, car il place un 'string' dans un' istringstream'. La conséquence est que s'il y a un échec d'analyse, l'entrée d'origine peut être affichée à l'utilisateur. Contre. Si le code lisait directement à partir d'un 'istream', au moment où l'erreur s'est produite, il est trop tard pour afficher la mauvaise entrée. – Dan

+0

Les flux de fichiers et de réseaux sont également des exemples utiles. L'implémentation de n'importe quel type de désérialisation au niveau du flux d'octets va être désordonnée, sauf si vos besoins sont très basiques. Pour les besoins plus importants, vous devez concevoir un protocole, puis l'implémenter. Le traitement des erreurs spécifiques (et peut-être la récupération des erreurs et/ou la redondance des données) peut être conçu, auquel cas le code deviendra évident. –

6

Oui j'utiliser l'opérateur >> (mais pas aussi souvent que l'opérateur < <).Il est très utile pour analyser les types définis par l'utilisateur dans leurs objets respectifs et ainsi centraliser l'analyse et le traitement des erreurs nécessaires. Il est également très utile pour analyser la représentation sous forme de chaîne d'un type énuméré. Par exemple, considérons un type énuméré représentant un fruit. Par exemple, considérons un type énuméré représentant un fruit. Vous pouvez utiliser l'opérateur >> pour analyser une chaîne (comme "apple", "banana", etc.) pour obtenir la valeur d'énumération correcte.

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; 
} 

Notez aussi l'utilisation de la méthode de setstate sur le istream pour définir l'état d'échec du flux est rencontré lorsque une chaîne inconnue. Lorsque vous utilisez cet opérateur, vous pouvez vérifier la failstate du flux comme suit:

Fruit fruit; 
std::cin >> fruit; 
if (std::cin.fail()) 
    std::cout << "Error: Unknown Fruit!" << std::endl; 
2

je ne les écrire et utiliser très rarement les « intégrés ». Les opérateurs d'extraction sont plutôt inutiles pour lire les entrées interactives de l'utilisateur, car il est trop facile pour un flux de se détériorer. L'écriture d'une routine d'analyse personnalisée est presque toujours plus facile et plus robuste. Et quand il s'agit de sérialisation, si je veux enregistrer quelque chose sous forme de texte, je le fais à un format standard de l'industrie tel que XML, que les opérateurs d'extraction sont particulièrement mal adaptés à la lecture. Sinon, je stocke les données dans une base de données ou dans un fichier binaire, qui, une fois de plus, ne conviennent pas aux extracteurs.

2

operator>> est utile pour convertir des nombres sous forme de texte en une représentation interne.

Il peut également être utile lors du chargement de données pour des objets. Contrairement à scanf, qui ne peut pas être surchargé pour différents types, les objets peuvent surcharger operator>>. Ainsi, il fournit plus de données cachées pour charger des objets, la représentation interne n'a pas besoin d'être connue pour lire des données dans l'objet.