11

直感的には、C ++の仕様から判断すると、次の呼び出しで文字を読み取るistream::putback( c )ように、常に入力バッファーを配置する必要があるように見えます。これは正しくありませんか?Xcode4.6に同梱されている最新バージョンのlibc++は、すべての場合、特に最後の文字がEOFにある場合に、この動作を強制するわけではないようです。の代わりにを使用する場合も同様です。istream::peek()cunget()putback( c )

libc ++の動作は正しいですか、それともどのように正しく機能するかについての私の直感はputback()/unget()正しいですか?

このサンプルコードを考えてみましょう。これはlibstdc++では機能しますが、libc ++では機能しません(アサーションは失敗します)。

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

2 に答える 2

6

実際にはputback、C++11の関数に変更が加えられています。

§27.7.2.3/34

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

効果:関数が最初にクリアされることを除いて、フォーマットされていない入力関数として動作します(27.7.2.3、段落1で説明されています)eofbit。..。

文の後半がC++03に存在しなかったところ。

したがって、コンパイラがこの変更を完全に実装したかどうか、または必要なオプション(-std=C++11?)を使用したかどうかによって異なる場合があります。

于 2013-02-11T21:03:24.727 に答える
4

BoPerssonは基準について正しいです。おそらく古いバージョンのlibc++を使用しています(問題は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(2012年8月25日土曜日)| 1行

basic_istream seekg、putbackを持ち、最初の明確なeofbitを取得します。http://llvm.org/bugs/show_bug.cgi?id=13089を修正 します。

于 2013-02-11T19:41:34.247 に答える