Подтвердить что ты не робот

Не должно istream:: peek() всегда возвращать то, что вы только что положили()?

Интуитивно, судя по спецификации С++, мне кажется, что istream::putback( c ) всегда должен упорядочивать входной буфер таким образом, чтобы следующий вызов istream::peek() должен читать символ c. Это неправильно? Я спрашиваю, потому что последняя версия libС++-доставки с Xcode 4.6, похоже, не обеспечивает такого поведения во всех случаях, особенно когда последний символ находится в EOF. То же самое верно, если вы используете unget() вместо putback( c ).

Правильно ли поведение libС++ или моя интуиция в том, как putback()/unget() должен работать правильно?

Рассмотрим этот пример кода, который работает с libstdС++, но не с libС++ (утверждение терпит неудачу).

#include <sstream>
#include <cassert>

int main(int argc, const char * argv[])
{
    std::istringstream in( "[Test]" );

    while( in )
    {
        int c = in.get();
        if( c == ']' )
        {
            in.putback( c );
            assert( in.peek() == c );   // Fails with libc++. Succeeds with libstdc++.
            break;
        }
    }

    return 0;
}
4b9b3361

Ответ 1

Фактически произошла смена функции putback в С++ 11:

§27.7.2.3/34

basic_istream<charT,traits>& putback(char_type c);

Эффекты: ведет себя как неформатированная входная функция (как описано в пункте 27.7.2.3, параграф 1), за исключением того, что функция сначала очищает eofbit....

Если вторая половина предложения не существовала в С++ 03.

Таким образом, это может зависеть от того, полностью ли реализованы компиляторы этого изменения или используются ли необходимые параметры (-std=C++11?).

Ответ 2

Бо Перссон правильно относится к стандартам. Вероятно, вы используете более старую версию libС++ (ваша проблема связана с Bugtracker LLVM, см. Ниже).

Это изменение было внесено в ревизию 162108:

--- istream     (revision 162607)
+++ istream     (revision 162608)
@@ -1263,6 +1263,7 @@
     try
     {
 #endif  // _LIBCPP_NO_EXCEPTIONS
+        this->clear(this->rdstate() & ~ios_base::eofbit);
         sentry __sen(*this, true);
         if (__sen)
         {

Журнал об изменении:

$svn log -r 162608

----------------------------------------------- ------------------------- r162608 | hhinnant | 2012-08-25 00:03:03 +0200 (суббота, 25 августа 2012) | 1 Линия

У вас есть basic_istream seekg, putback и unget first clear eofbit. Исправления http://llvm.org/bugs/show_bug.cgi?id=13089.