0

I am trying to get a function to be recognized as a friend but I can not figure out what I am doing wrong. I tried changing things to references and moving things in and out of the namespace and header cpp. There is nothing that I notice as the culprit for why this does not work.

The error I am getting is

error: call to deleted constructor of 'std::__1::ostream' (aka 'basic_ostream<char>')
          return output;
                 ^~~~~~

I'm thinking it might be a reference issue, or maybe something I forgot to import when I started. But I can't think of anything.

namespace N 
{
    class Complex
    {
    public:
        // Contructors
        Complex(double n, double i)
        {
            this->number = n;
            this->imaginary = i;
        }

        Complex()
        {
            this->number = 0;
            this->number = 0;
        }

        // Accessors
        friend ostream operator<< (ostream& os, const Complex& a);

        // Operator Overloads
        Complex operator + (Complex b)
        {
            Complex c;
            c.number = this->number + b.number;
            c.imaginary = this->imaginary + b.imaginary;
            return c;
        }

    private:
        double number;
        double imaginary;
    };

    ostream operator<<(ostream& output, const Complex& a) 
    {
        output << fixed << setprecision(1) << a.number << " + " << a.imaginary << "i";
        return output;
    }
}
JeJo
  • 30,635
  • 6
  • 49
  • 88
ron252
  • 21
  • 8
  • noted: Right now the error is "Call to deleted constructor of std::__1::ostream" – ron252 Sep 16 '21 at 05:17
  • Oh, no idea what that means. Thanks for the knowledge – ron252 Sep 16 '21 at 05:22
  • Changing the question title is not enough. The title should *summarize* the issue, and there is more information in an error message than belongs in a summary. The entire error message should have been copied verbatim into the question body (as I have taken the liberty of demonstrating -- but I left off the line number and character position; normally leave these in the paste). Note that error messages typically occupy more than one line. In this case, the second and third lines point out exactly where the error was detected, without the need to count lines and character positions. – JaMiT Sep 16 '21 at 15:56

1 Answers1

3

You need to return the std::ostream by reference. That means you need

namespace N 
{
    class Complex 
    {
    public:
        friend std::ostream& operator<< (std::ostream& os, const Complex& a);
        //     ^^^^^^^^^^^^^^

    private:
        // ...
    };

    std::ostream& operator<<(std::ostream& output, const Complex& a)
    //^^^^^^^^^^^^
    {
        
        return output << std::fixed << std::setprecision(1) 
                      << a.number << " + " << a.imaginary << "i";
    }
}

This is because, the std::ostream is non-copyable:

protected:
basic_ostream( const basic_ostream& rhs ) = delete; (2) (since C++11)

When you return by non-reference, it will be return by copy in operator<<, which required the copy constructor call. Since it is deleted, you get the error.

JeJo
  • 30,635
  • 6
  • 49
  • 88