16

私の問題は次のとおりです。MartinYorkは、これこれ、およびこれstringstreamは、次のように使用することで、あるメモリから読み取ることができると答えていますbasic_stringbuf::pubsetbuf

char buffer[] = "123";
istringstream in;
in.rdbuf()->pubsetbuf(buffer, sizeof(buffer)); // calls basic_stringbuf::setbuf
int num;
in >> num; // reads 123

残念ながら、私は標準全体を掘り下げて、それがどこで機能することが保証されているのかわかりませんでした。私が見ているのは、それは単なる実装定義です。実際、Microsoftの実装(おそらく他の実装でも)では、この呼び出しは効果がありません。

これが、前回のC++0xドラフトで見つけた関連する引用です。basic_streambuf::setbuf[streambuf.virt.buffer]の場合:

1効果:この節(27.8.1.4、27.9.1.5)のbasic_streambufから派生したクラスごとに個別に定義される方法で、ストリームのバッファリングに影響を与えます。

2デフォルトの動作: 何もしません。これを返します。

ただし、派生クラスでは、動作は実装定義のままになっているようです。それbasic_stringbuf::setbufは[stringbuf.virtuals]と言っています:

1効果: setbuf(0,0)が効果を持たないことを除いて、実装定義。

それbasic_filebuf::setbufは[filebuf.virtuals]と言っています:

12効果: setbuf(0,0)[...]の場合、ストリームはバッファリングされなくなります。それ以外の場合、結果は実装定義です。「バッファなし」[...]

以上です。したがって、私が見ているように、有効な実装はこれらの呼び出しを完全に無視できます(null以外のパラメーターの場合)。

私が間違っている?規格の正しい解釈は何ですか?C ++ 98/03 / 0xにも同じ保証がありますか?上記のコードが機能する実装と機能しない実装について、より多くの統計がありますか?どのようbasic_streambuf::setbufに使用することを意図していますか?

4

2 に答える 2

8

実装が定義されており、関連する見積もりを提供されたと思います。

ちなみに、これは標準のC ++ IOStreamsとロケールであり、私が認めなければならない最近の本ではありませんが、「ほぼセマンティックなフリー関数-setbuf()」というタイトルのセクションでこの件について述べています。

仮想メンバー関数setbuf() は、かなり特殊なストリームバッファーメンバーです。そのセマンティクスは基本的に未定義です。文字列ストリームバッファの場合、のセマンティクスは実装によって定義されますが、定義されている場合 setbuf()を除き ます。以前にストリームで呼び出され、そのストリームでI / Oが発生した場合、ストリームはバッファリングされなくなります。つまり、文字はファイルシステム。それ以外の場合、結果は実装によって定義されます。setbuf(0, 0)setbuf(0, 0)

ただし、 setbuf()forの仕様は、他のストリームバッファタイプのセマンティクスに要件を課すことはほとんど basic_filebufあり ません。せいぜい、一般的なセマンティクスはデバイスとして定義でき、ユーザー定義のストリームバッファータイプの場合は実装固有として定義できます。basic_stringbufsetbuf()

要件がないsetbuf()ため、ほぼすべての目的で、の事前定義されたインターフェイスに適合する方法で 再定義できますsetbuf()

于 2010-12-06T21:50:22.633 に答える
4

わかった。撤回します。

過去数日間、ドキュメントと作成された提案を確認した後、これが機能しない可能性があることは明らかです(実装で定義されているため)。

上記の説明で述べたように:

27.5.2.4.2:1効果:この節(27.8.1.4、27.9.1.5)のbasic_streambufから派生したクラスごとに個別に定義される方法で、ストリームのバッファリングに影響を与えます。

setbuf()の効果は、実際には27.8.1.4 underflow()との相互作用によって定義されます。

戻り値:入力シーケンスに使用可能な読み取り位置がある場合、traits :: to_int_type(* gptr())を返します。それ以外の場合は、traits :: eof()を返します。初期化された基になるバッファ内の文字は、入力シーケンスの一部と見なされます

また、ストリームからより多くの文字を取得するには、27.9.1.5 showmanyc()を確認する必要があります。

実装は、入力シーケンスからより多くの文字を読み取ることができると判断できる場合、この関数シグネチャのオーバーライド定義を提供する可能性があります。

文字列ストリームバッファの場合、バッファはすでにストリーム全体を保持しているため、何も取得されないことを意味します。

ですから、それは実装によって定義されていますが、それをどのように行うかを定義しています。
それがどのように行われるかはまだ明確に定義されています。

于 2010-12-03T21:26:23.330 に答える