2

C++ iostream マニピュレーターを実装する必要があります。あちこちで読むと、人々は2つの方法を使用しているようです

  1. を使用ios_base::xallocしてios_base::iword

  2. 以下の例のように、iostream から派生したクラスを実装します。

私は 2 番目の方法が好きですが、おそらく最初の方法と比較して、私には見えない、または理解できないという短所があります。

    // Example of point 2
    struct mystream : public iostream
    {  
      ostream& o_;
      mystream(ostream& o) : o_(o) {} 

      ostream& operator << (int a) {
        // do something with o and a
        o << "<A>" << a << "</A>";
        return *this;
      }     
     };

     ostream mymanipulator(ostream& out) { 
       return mystream(out);
     }

この記事Custom manipulator for C++ iostreamで方法 2 の非常に優れた実装を見つけました。

xalloc and iwordカスタムストリームをある時点で使用するために、カスタム内部状態を保存するために使用されているように見えます。

4

1 に答える 1

2

私はそれらのどちらもお勧めしません。

ios_base::xallocと_ios_base::iword

ストリームに保存されたデータをどのように使用するかを正確に教えてくれませんでしたが、iword()書き込みたいたびに設定するのは少し直感的ではありません.

からの派生クラスを実装していiostreamます...

通常、ストリームの基本クラスから継承する必要はありません。これが役立つ唯一のケースは、カスタム ストリームをストリーム バッファーにラップする場合ですが、通常は利便性のためです。

もう 1 つの問題は、inserter が を返すことstd::ostreamです。つまり、演算子を連鎖std::ostreamさせると、2 回目の書き込みでベース オブジェクトにのみ書き込むことになります。

mystream str;
str << 100  // writes "<A>100</A>"
    << 200; // only writes 200

慣用的な解決策はstd::num_put<char>、ストリームのロケールに合わせてファセットをカスタマイズすることです。このようにして、ユーザーがストリームを使用する方法を変更しないように、機能をストリームのフードの下に直接ラップします。

于 2014-05-29T14:12:34.053 に答える