1

<< 演算子をオーバーロードして通貨を出力しようとしています (ユーザー定義型)

#include <iostream>
using namespace std;

struct Currency
{
  int Dollar;
  int Cents;

  ostream& operator<< (ostream &out)
  {
    out << "(" << Dollar << ", " << Cents << ")";
    return out;
  }
};



template<typename T>
void DisplayValue(T tValue)  
{
   cout << tValue << endl;
}

int main() {

Currency c;
c.Dollar = 10;
c.Cents = 54;

DisplayValue(20); // <int>
DisplayValue("This is text"); // <const char*>
DisplayValue(20.4 * 3.14); // <double>
DisplayValue(c); // Works. compiler will be happy now. 
return 0;
}

しかし、次のエラーが発生します。

prog.cpp: In instantiation of ‘void DisplayValue(T) [with T = Currency]’:
prog.cpp:34:16:   required from here
prog.cpp:22:9: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
    cout << tValue << endl;
         ^
In file included from /usr/include/c++/4.8/iostream:39:0,
                 from prog.cpp:1:
/usr/include/c++/4.8/ostream:602:5: error:   initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Currency]’
     operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
     ^

ここで何か不足している、または何か間違っている場合、誰かが私を助けることができますか?

4

6 に答える 6

7

最初に、2 番目のパラメーターとして を追加してオペレーターを修正する必要がありCurrency const& cます (右側に s があるため)。

次に、2 つのオプションがあります。

1: 友達追加

struct Currency
{
  int Dollar;
  int Cents;

  friend ostream& operator<< (ostream &out, Currency const& c)
  {
    return out << "(" << c.Dollar << ", " << c.Cents << ")";
  }
};

2: 定義をクラス外に移動する

struct Currency
{
  int Dollar;
  int Cents;
};

ostream& operator<< (ostream &out, Currency const& c)
{
  return out << "(" << C.Dollar << ", " << c.Cents << ")";
}

どちらでも動作し、問題ありません。
個人的には、出力演算子とそれが出力するクラスとの密結合を説明するオプション 1 が好きです。しかし、これは非常に単純なケースであり、どちらでも問題なく機能します。

メンバーになれない理由は、最初のパラメーターがストリームであるためです (演算子の左側の値が最初のパラメーターです)。最初のパラメーターは非表示の this パラメーターであるため、これはメンバーには機能しません。したがって、技術的には、このメソッドを に追加できますstd::ostream。残念ながら、変更にアクセスすることはできません (許可されていません) std::ostream。その結果、独立した関数にする必要があります。

メンバーになれることを示す例:

struct X
{
    std::ostream operator<<(int y)
    {
        return std::cout << y << " -- An int\n";
    }
};
int main()
{
    X   x;
    x << 5;
}

ここではうまくいきます。これは、コンパイラが変換するためです。

x << 5;

の中へ

// not real code (pseudo thought experiment code).
operator<<(x, 5)
      // Equivalent to:
                X::operator<<(int y)
      // or
                operator<<(X& x, int y) 

x にはメンバー関数があるため、operator<<これは正常に機能します。xメンバー関数が呼び出されていない場合、コンパイラは、1 番目と2 番目のoperator<<2 つのパラメーターを取る独立した関数を探します。Xint

于 2013-10-23T22:22:32.407 に答える
0

インサータ メソッドを記述した方法で動作させる唯一の方法は、次のようにすることです。

c << std::cout;

ただし、代わりに、インサーターがプライベート変数にアクセスする必要がないことがわかっている場合は、他の回答が言うように、両方の引数を取るグローバル関数を作成してください。

std::ostream& operator <<(std::ostream& os, const Currency& c);
于 2013-10-23T19:30:45.583 に答える
-2

友達にする必要があります。また、正しい引数を与える必要があります。ostream と通貨。

  friend ostream& operator<< (ostream& stream, const Currency& c )
  {
    stream << "(" << c.Dollar << ", " << c.Cents << ")";
    return stream;
  }

編集:
コメントでわかるように、友達にする必要はありません。構造の外に置くことができます。

Currency c;
c.Dollar = 10;
c.Cents = 54;

DisplayValue(c); // Works. compiler will be happy now. 
于 2013-10-23T19:00:47.423 に答える