web-dev-qa-db-fra.com

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

J'ai utilisé "Accelerated C++" pour apprendre le C++ au cours de l'été, et il y a un concept que je ne semble pas comprendre correctement.

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 entrons dans notre clavier?

47
Muhsin Ali

cin est un objet de classe istream qui représente le flux d'entrée standard. Il correspond au cstdio stream stdin. L'opérateur >>overload pour les flux renvoie une référence au même flux. Le flux 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 flux formatée. L'opération cin >> x;

où "x" est un int échouera si une valeur non numérique est entrée. Donc:

if(cin>>x)

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

Ce site Web sur trucs et astuces en utilisant les E/S C++ vous aidera également.

59
user195488

Remarque: la réponse a été mise à jour quatre ans après coup pour traiter à la fois C++ 98/03 et C++ 11 (et au-delà).


std::cin Est une instance d'un std::istream. Cette classe fournit deux surcharges liées à cette question.

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

Une instruction if a 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 n'est rien de ce qui précède. Cependant, la classe istream possède 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. Il s'agit de l'opérateur de conversion spécifique à la version que la langue utilise pour le test if. Étant donné que l'échec de la lecture marque le flux comme non valide, le test if échouera si la lecture n'a pas fonctionné.

La raison du membre de conversion operator void* Plus compliqué avant C++ 11 est que ce n'est qu'en C++ 11 que le mot clé explicit déjà existant a été étendu pour s'appliquer aux opérateurs de conversion en tant que ainsi que les constructeurs. Une operator bool() non explicite aurait présenté beaucoup trop d'occasions aux programmeurs de se tirer une balle dans le pied. Il y a également des problèmes avec operator void*(). "L'idiome de booléen sûr" aurait été un correctif, mais simplement étendre explicit a accompli exactement ce que l'idiome de booléen sûr accomplit, et sans avoir à utiliser beaucoup de magie SFINAE.

33
David Hammen

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

La classe istream remplace la >> pour effectuer la saisie et renvoyer une référence à l'objet sur lequel vous l'avez appelé (cin).

7
SLaks

cin est variable dans std namespace.

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

6
Olympian

Les réponses ci-dessus sont informatives. Ici, je donne juste un commentaire supplémentaire.

std::cin Est un objet de classe istream et représente le flux d'entrée standard (ie le clavier) qui correspond à stdin dans le flux C .

cin >> x Lit d'abord un entier dans le flux d'entrée standard et l'affecte à x. Après cela, renvoyez une auto référence à cin. Ainsi, la valeur de retour de l'appel de fonction cin >> x Est toujours cin.

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

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

ou

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

De ces deux déclarations, nous savons qu'ils cast le type de flux directement ou indirectement (via void* Pointeur vers bool ce qui est évident) en bool type.

Dans ces deux fonctions, elles dépendent de certains états de base IO Steam (champs de classe) pour déterminer si retourner faux ou vrai (pour void* cas, c'est nullptr ou pas).

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

4
Zachary

parce que le résultat de l'expression

cin >> x

évalue à

cin

après la lecture du flux.

4
Erix

Comme je sais, l'opérateur surchargé >> retourne un objet de classe istream. Voilà pourquoi ici n'est pas différent

0
Vitaly Davydov

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

2) l'opérateur >> De istream renverra son opérande gauche, dans ce cas c'est cin, voir http://www.cplusplus.com/ référence/istream/istream/operator% 3E% 3E / . Cet opérateur activera failbit si aucun caractère n'a été extrait de cin, au cas où le lecteur a terminé EOF donc il n'y aura plus de caractère à lire.

3) À 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 que ce bloc if renverra:

  • Un pointeur nul si au moins l'un de failbit ou badbit est défini. Sinon, une autre valeur (pour la norme C++ 98).

  • La fonction renvoie false si au moins un de ces indicateurs d'erreur est défini, et true sinon. (pour la norme C++ 11)

0
Ryan Le

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

0
Emil Condrea