2

取り組んでいる課題に問題があります。独自の名前空間内で定義される複素数クラスを作成しています。istream と ostream のオーバーロードを除いて、すべてが機能しています。私のコードの一部を投稿させてください:

namespace maths {

    class complex_number{
    public:

        // lots of functions and two variables

        friend std::istream& operator >>(std::istream &in, maths::complex_number &input);

    }
}

std::istream& operator >>(std::istream &in, maths::complex_number &input)
{
   std::cout << "Please enter the real part of the number > ";
   in >> input.a;
   std::cout << "Please enter the imaginary part of the number > ";
   in >> input.b;

   return in;
}

int main(int argc, char **argv)
{
   maths::complex_number b;
   std::cin >> b;

   return 0;
}

私が得ているエラーは次のとおりです。

com.cpp: In function ‘int main(int, char**)’:
com.cpp:159:16: error: ambiguous overload for ‘operator>>’ in ‘std::cin >> b’
com.cpp:159:16: note: candidates are:
com.cpp:131:15: note: std::istream& operator>>(std::istream&, maths::complex_number&)
com.cpp:37:26: note: std::istream& maths::operator>>(std::istream&, maths::complex_number&)

ここでフォーラムを熟読し、名前の非表示に関する回答に出くわしましたが、コードで機能させることができないようです。どんな助けでも大歓迎です!

4

1 に答える 1

3

あいまいな理由は、2 つの別個の機能があるためです。maths1 つは名前空間に存在しfriend、クラス内でマークされたものによって宣言されます。これは、Argument Dependent Lookup で見つけることができます。名前空間の外にも完全な定義があります。これらはどちらも等しく有効です。

まず、クラスのプライベート メンバーにアクセスしていないため、friend宣言は必要ありません。カプセル化を損なうだけなので、友達にしないでください。

次に、定義をmaths名前空間に移動することをお勧めします。これは、操作対象のクラスと一緒にそこに属しているためです。前に述べたように、2 番目の引数はその名前空間の型であるため、ADL は引き続きそれを見つけます。そのため、名前空間が検索され、オーバーロードが見つかります。

全体として、次のようになります。

namespace maths {

    class complex_number{
    public:
        // lots of functions and two variables
    };

    std::istream& operator >>(std::istream &in, maths::complex_number &input)
    {
       std::cout << "Please enter the real part of the number > ";
       in >> input.a;
       std::cout << "Please enter the imaginary part of the number > ";
       in >> input.b;

       return in;
    }
}

int main(int argc, char **argv)
{
   maths::complex_number b;
   std::cin >> b; //operator>> found by ADL

   return 0;
}

最後に、オーバーロード自体について説明します。Input は実際には入力を要求するべきではありません。入力を読み取るだけです。このようにして、キーボード、ファイル、または必要なその他の派生物で使用できますstd::istream

于 2013-08-15T03:41:41.913 に答える