if (cin >> x) – Pourquoi pouvez-vous utiliser cette condition?

J’utilise “Accelerated C ++” pour apprendre le C ++ au cours de l’été et il y a un concept que je ne comprends pas bien.

Pourquoi est-ce

int x; if (cin >> x){} 

équivalent à

 cin >> x; if (cin){} 

En regardant le code, il me semble que nous utilisons cin comme variable. Mais je pensais que c’était une fonction. Pourquoi pouvons-nous utiliser cin de cette manière quand c’est x qui a la valeur que nous saisissons dans notre clavier?

cin est un object de classe istream qui représente le stream d’entrée standard. Il correspond au stream cstdio stdin . L’opérateur >> surcharge pour les stream renvoie une référence au même stream. Le stream lui-même peut être évalué dans une condition booléenne à true ou false via un opérateur de conversion.

cin fournit une extraction de stream formatée. L’opération cin >> x;

où “x” est un int échouera si une valeur non numérique est entrée. Alors:

 if(cin>>x) 

renverra false si vous entrez une lettre plutôt qu’un chiffre.

Ce site Web sur les trucs et astuces utilisant C ++ I / O vous aidera également.

Note: Réponse mise à jour quatre ans plus tard pour traiter à la fois C ++ 98/03 et C ++ 11 (et au-delà).

std::cin est une instance de std::istream . Cette classe fournit deux surcharges relatives à cette question.

  • operator >> lit les données du stream dans la variable cible si cela est possible. Si le contenu immédiat du stream ne peut pas être traduit dans le type de la variable cible, le stream est plutôt marqué comme non valide et la variable cible rest intacte. Indépendamment du succès / de l’échec de l’opération, la valeur de retour est une référence au stream.
  • Soit l’ operator void*() (pre-C ++ 11), qui convertit la référence de stream en un pointeur void* , ou explicit operator bool() (C ++ 11), qui convertit la référence de stream en booléen. Le résultat de cette conversion est un pointeur non nul (pré-C ++ 11) ou true (C ++ 11) si le stream est valide, mais le pointeur nul (pré-C ++ 11) ou false (C + +11) si le stream n’est pas valide.

Une instruction if besoin d’un booléen, d’un entier ou d’un pointeur comme quantité à tester. Le résultat de std::cin >> x est une référence à un istream , qui ne correspond à rien de ce qui précède. Cependant, la classe istream a ces opérateurs de conversion qui peuvent être utilisés pour transformer la référence istream en quelque chose utilisable dans une instruction if . C’est l’opérateur de conversion spécifique à la version que le langage utilise pour le test if . Le défaut de lecture indiquant que le stream est invalide, le test if échoue si la lecture ne fonctionne pas.

La raison de la conversion plus complexe de l’ operator void* antérieures à C ++ 11 est que ce n’est qu’au C ++ 11 que le mot-clé explicit déjà existant a été étendu pour s’appliquer aux opérateurs de conversion ainsi qu’aux constructeurs. Un operator bool() non explicite operator bool() aurait présenté beaucoup trop d’occasions pour les programmeurs de se tirer dans le pied. Il y a aussi des problèmes avec l’ operator void*() . Le “idiome de sécurité bool” aurait été un correctif, mais simplement étendre explicit accomplissait exactement ce que fait l’idiome de sécurité bool, et sans avoir à utiliser beaucoup de magie SFINAE.

cin est une variable (globale) de type istream , pas une fonction.

La classe istream remplace l’opérateur >> pour effectuer une saisie et renvoyer une référence à l’object sur cin vous l’avez appelée ( cin ).

cin est variable dans l’espace de noms std .

operator>> renvoie la référence à cin , à cause de cela vous pouvez écrire: cin >> a >> b , au lieu de cin >> a; cin >> b; cin >> a; cin >> b;

parce que le résultat de l’expression

 cin >> x 

évalue à

 cin 

après la lecture du stream.

Les réponses ci-dessus sont informatives. Ici, je viens de donner un commentaire supplémentaire.

std::cin est un object de classe istream et représente le stream d’entrée standard (le clavier) qui correspond à stdin dans le stream C.

cin >> x lirait d’abord un int du stream d’entrée standard et l’affecterait à x . Après cela, retournez une référence automatique à cin . Donc, la valeur de retour de l’appel de fonction cin >> x est toujours cin .

Donc, du sharepoint condition si , if(cin) et if(cin >> x) ressemblent. La bibliothèque IO standard définit une fonction pour le stream comme ceci (dépend de l’implémentation):

 explicit operator bool() const; // C++11 

ou

 operator void*() const; //C++98, C++2003 

À partir de ces deux déclarations, nous soaps qu’elles jettent le type de stream directement ou indirectement (par le biais de void* pinter vers bool ce qui est évident) en type bool .

Au sein de ces deux fonctions, elles dépendent de certains états de base IO steam (champs de classe) pour déterminer si les valeurs false ou true sont renvoyées (pour les void* case, nullptr ou non).

cin est une instance de classe istream qui hérite de la fonction casting-to-bool . Donc ça marche!

Parce que cin est un object de classe, lisez plus sur http://www.cplusplus.com/reference/iostream/cin/ .

Comme je le sais, l’opérateur surchargé >> renvoie un object de classe istream. Il y a pourquoi ici n’est pas différent

1) cin est une instance de istream , voir http://www.cplusplus.com/reference/iostream/cin/ .

2) l’opérateur >> d’ istream retourne son opérande gauche, dans ce cas il est cin , voir http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/ . Cet opérateur failbit le défaut si aucun caractère n’a été extrait du cin , au cas failbit le lecteur aurait terminé EOF , il n’y aurait plus de caractère failbit lire.

3) A partir du 2) ci-dessus, lorsque la condition est évaluée après l’opération de lecture, if (cin >> x) doit être comme if (cin) , reportez-vous à ce lien http://www.cplusplus.com/reference/ ios / ios / operator_bool / vous verrez cela, ceci if bloc retournera:

  • Un pointeur nul si au moins l’un des failbit ou des badbit est défini. Une autre valeur sinon (pour le standard C ++ 98).

  • La fonction renvoie false si au moins l’un de ces indicateurs d’erreur est défini et true dans le cas contraire. (pour le standard C ++ 11)