0

g++ 4.4.5

クラス std::ofstream を拡張していくつかの機能を追加するクラスがあります。

 MyStream& MyStream::operator<<(const bool& val) {
  if(this->pos == 8) {
    this->pos = 0;
    ofstream::operator<<(this->curbyte); //call the parent method
  }
  curbyte = curbyte + (val << pos++);
  return *(this);
}

これにより、基本的に個々のビットをブール値として書き込むことができ、親の << メソッドを使用して 8 つの各セットを書き込むことができます。基本メソッドを呼び出していたため、ここではこの呼び出し構文を使用する必要がありましたが、このクラスを使用する実際のメイン メソッドでは、次の行を呼び出そうとしました。

bout << (unsigned char) 255u;

ofstream および unsigned char に対して既に定義されている << メソッドを呼び出したいのですが、ofstream (char、unsigned char、signed char) および独自の bool メソッドに対して既に定義されているすべての char 関連の候補をリストする、長くあいまいなオーバーロード エラーが表示されます。 、明示的にcharにキャストしましたが。しかし、私はそれを次のように動作させることができました:

bout.operator<<((unsigned char) 255u);

これは、g++ が暗黙のキャストを行う方法と関係があるに違いありません (私の推測では、最初のケースでユーザー定義のキャストの後に、もう 1 つの可能なキャストがあり、関数呼び出し構文が回避することを曖昧にしています)。なぜこれが起こっているのか、またはエラーを回避するより良い構文があるのか​​ を正確に知っている人はいますか?

4

2 に答える 2

5

メンバー関数として定義されているoperator<<instd::ostreamは are notvirtualです。operator<<この関数のすべての基本クラス バージョンを非表示にするため、オーバーロードの解決では表示されません。ただし、operator<<フリー関数として定義されている は表示されます。

、およびすべてoperator<<の無料関数です。charunsigned charsigned char

これはbout << (unsigned char) 255u、メンバー関数と、を受け取るフリー関数のunsigned char両方が、オーバーロード解決のために可視であることを意味します。

を受け取る free 関数を呼び出すにはunsigned char、クラス インスタンスを基本クラスへの参照にバインドする必要があります。これは「変換」としてカウントされますが、右側は変換を必要としません。メンバー関数を呼び出すには、unsigned char再度bool「変換」に変換する必要がありますが、左側は変換を必要としません。これらの変換シーケンスはどちらも他より優れていないため、呼び出しがあいまいです。

于 2010-11-12T07:44:30.283 に答える
2

これは、iostream を初めて使用する人 (つまり、データを別の方法で出力したいために新しいストリーム タイプを派生させる) によくある失敗です。

また、独自の操作を追加することもできません。つまり、iomanip を拡張することはできません。

別の形式でデータを出力する正しい方法は、出力したいデータの周りにラッパーを置くことです:

ostream& os << my_formatter(t);

さまざまなタイプの t に対して。

特殊化されていない限り、t を返すだけのテンプレート関数として my_formatter を使用できます。複数の引数を指定することもできます。(基になるデータへの参照を含むクラスを返し、operator<< オーバーロードされます)。

于 2010-11-12T08:37:34.420 に答える