ce qui est le résultat d'incrémenter un istream_iterator qui est déjà à la fin du cours d'eau?

StackOverflow https://stackoverflow.com/questions/1307831

  •  19-09-2019
  •  | 
  •  

Question

Je l'ai regardé la norme et ne voit pas de réponse évidente.

Supposons que je l'ai fait:

std::istream_iterator<char> is(file);
while(is != std::istream_iterator<char>()) {
    ++is;
}

maintenant is est à la fin du flux et est égal à std::istream_iterator<char>(). Que faire si j'incrémenter une fois de plus? Est-il encore égal à std::istream_iterator<char>()? ou os le résultat indéfini?

La norme stipule explicitement que *is est un comportement non défini si is est à la fin du flux. Mais je ne l'ai pas vu quoi que ce soit en ce qui concerne itérer après la fin du cours d'eau ...

EDIT :

Je demande parce que je suis tombé sur un code qui fait quelque chose comme ceci:

// skip 2 input chars
++is;
++is;
if(is != std::istream_iterator<char>()) {
    // continue using is and do some work...but what if the first
    // increment made it EOS? is this check valid?
}
Était-ce utile?

La solution

Tableau 72 en C ++ 03 sur les exigences d'entrée iterator dit que la condition préalable de ++r est que r est de-référençables. Les mêmes conditions préalables pour r++ détient.

Maintenant, 24.5.1/1 dit à propos istream_iterator

  

Le résultat de operator* sur une extrémité de flux est non définie.

En conclusion, les effets de operator++ sur un itérateur de fin de cours d'eau ne sont pas définies.

Tableau 72 en C ++ 03 sur les exigences d'entrée iterator dit que la condition préalable de ++r est que r est de-référençables. Les mêmes conditions préalables pour r++ détient.

Maintenant, 24.5.1/1 dit à propos istream_iterator

  

Le résultat de operator* sur une extrémité de flux est non définie.

En conclusion, les effets de operator++ sur un itérateur de fin de cours d'eau ne sont pas définies.


Notez que je pense que cette conclusion rend un comportement non défini que lorsque vous écrivez ou utilisez un algorithme prenant itérateurs d'entrée qui présente ce comportement, et passez ensuite un iterator istream. À partir de seulement avec la iterator istream lui-même explicitement, sans le traiter comme un itérateur d'entrée et se fondant sur ses invariants, alors je pense au-dessus de la conclusion n'est pas tout à fait raison (nous pouvons avoir une classe qui ne exiger que r est dereferenceable, par exemple).

Mais en regardant comment istream iterator est décrit, une invocation de operator++ après avoir atteint la fin des résultats de la valeur de flux de comportement non défini soit. operator== car il est défini comme étant équivalent à

x.in_stream == y.in_stream

in_stream est un pointeur sur le flux itéré - et exposé dans le texte standard pour définir le comportement et la sémantique « exposition uniquement ». Maintenant, la seule mise en œuvre que je peux penser qui fait ce travail, utilise un itérateur de fin de cours d'eau qui stocke en tant que flux pointer un pointeur NULL. Mais operator++ est défini comme faisant quelque chose ayant l'effet des éléments suivants

*in_stream >>value

Maintenant, si vous entrez dans l'état de fin de cours d'eau, et nous définiriez in_stream à un pointeur NULL, alors sûrement l'effet de ce serait un comportement non défini.

Donc, même si vous utilisez le iterator istream seul, il ne semble pas y avoir de garantie que vous pouvez augmenter après la fin de chaîne de valeur.

Autres conseils

S'il est pas défini, il est :-) non défini dans la norme (dernière version de C ++ 0X) mots, l'accent est à moi:

  

comportement non défini

     comportement

, comme pourraient résulter d'une utilisation d'une construction de programme erroné ou des données erronées,   Pour qui   la présente Norme internationale impose aucune exigence. comportement non défini peut également être prévu   lorsque cela   Norme internationale omet la description d'une définition explicite du comportement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top