6

次のコードがあります。

struct simple
{
    simple (int a1, int a2) : member1(a1), member2(a2) {}
    int member1;
    int member2;
};

std::ofstream &operator << (std::ofstream &f, const simple &obj)
{
    f<<obj.member1<<", "<<obj.member2;
    return f;
} 
int main(int argc, const char *argv[])
{
    std::ofstream f("streamout.txt");

    simple s(7,5);
    f << s;               //#1 This works
    f << "label: " << s;  //#2 This fails

    return 0;
}

#1が機能する理由を理解しようとしていますが、#2のように連結するオーバーロードされた演算子を使用しようとすると問題が発生し、次のエラーで失敗します(MacOSXのgcc 4.5.3):

エラー: 'std::basic_ostream' 左辺値を 'std::basic_ostream&&' /GCC-FACTORY/4.5/INSTALL/lib/gcc/x86_64-apple-darwin10.5.0/4.5.3/../../ にバインドできません。 ./../include/c++/4.5.3/ostream:579:5: エラー: 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits, _Tp = simple]'

代わりに、演算子を次のように定義すると、すべて問題ありません

std::ostream &operator << (std::ostream &f, const simple &obj)
{ ... }

オーバーロードの解決に関連するもののように聞こえます。オーバーロードが既に提供されている ofstream に何かが挿入されている場合 (この場合は const char * "label")、オーバーロードの解決後に分割されますが、正確に何を理解することはできませんがここで行われています。コンパイラが何をしようとしているのかを明確に把握したいと思います..

4

1 に答える 1

17

ライン上:

f << "label: " << s;

への最初の呼び出しoperator<<は a を返すためstd::ostream &、2 番目の呼び出しはコンパイルに失敗します。演算子の左側のオペランドはstd::ofstreamもはや型ではなく、オーバーロードが見つかりません。

タイプを に出力するように制限する理由が見当たらないので、実際には 2 番目の署名を使用する必要がありますstd::ofstream

于 2011-01-09T18:46:45.750 に答える