0

I have a Class called "Vector". It consists of two private fields: std::vector<double> coordinates and int len. Methoddim() returns len.

I am overloading operator << like that:

friend std::ostream& operator<<(std::ostream& os,  Vector& vec ) 
{
    std:: cout << "(";
    for ( int i = 0; i < vec.dim(); i++ ) {
        if ( i != vec.dim()-1){
            os << vec[i] << ", ";
        } else {
            os << vec[i];
        }
    }
    os << ')';
    return os;
}

An operator + like that:

friend Vector operator +(Vector& first, Vector& second)
{
    if(first.dim() != second.dim()){
        throw std::length_error{"Vectors must be the same size"};
    }else {
        Vector localVec(first.dim()); // same as {0,0,0...,0} - first.dim() times 
        for (int i = 0; i < first.dim(); i++){
            localVec[i] = first[i] + second[i];
        }
        return localVec;
    }
}

And operator [] like that:

double& operator[](int index)
{
    return this->coordinates[index];
}

And here's the problem:

Vector x{1,2,4};
Vector y{1,2,3};
    
Vector z = x + y; 
std:: cout << z; // it works perfectly fine - (2, 4, 7)

std:: cout << x + y; // it gives me an error 
  • could not match 'unique_ptr<type-parameter-0-2, type-parameter-0-3>' against 'Vector' operator<<(basic_ostream<_CharT, _Traits>& __os, unique_ptr<_Yp, _Dp> const& __p)

It seems to me that this error is related to parameter Vector& vec , but I don't know whether it's right and what should I do to fix it. If anyone could give me a hint (or tell me what I should read more about) - I would be very grateful.

Here's full code:

 class Vector
{
    private:
        std::vector <double> coordinates;
        int len;
    public:
        Vector(): len{0}, coordinates{} {};
        Vector(std::initializer_list <double> coordinates_): len{static_cast <int>( coordinates_.size())}, coordinates{coordinates_} {}
        Vector(int len) : len{len} {
            for(int i = 0; i < len; i++){
                coordinates.push_back(0);
            }
        }
        int dim() const
        {
            return this->len;
        }

        double& operator[](int index)
        {
            return this->coordinates[index];
        }

        friend std::ostream& operator<<(std::ostream& os,  Vector& vec ) 
        {
            std:: cout << "(";
            for ( int i = 0; i < vec.dim(); i++ ) {
                if ( i != vec.dim()-1){
                    os << vec[i] << ", ";
                } else {
                    os << vec[i];
                }
            }
            os << ')';
            return os;
        }

        friend Vector operator +(Vector& first, Vector& second)
        {
            if(first.dim() != second.dim()){
                throw std::length_error{"Vectors must be the same size"};
            }else {
                Vector localVec(first.dim());
                for (int i = 0; i < first.dim(); i++){
                    localVec[i] = first[i] + second[i];
                }
                return localVec;
            }
        }
};
8
  • 2
    please post a minimal reproducible example. The error complains about a unique_ptr in your real code, but in the code you posted there is none Commented Aug 22, 2022 at 20:50
  • 1
    You should be more consistent in your coding guidelines. Prefer not to use this-> sequence more. You proved you don't need it, in the constructor and operator+. Commented Aug 22, 2022 at 21:06
  • 1
    @BorisBorais On a side note: inside your operator<<, std:: cout << "("; should be os << '('; instead. Commented Aug 22, 2022 at 21:08
  • 1
    Never use lvalue reference in sake of optimization (instead of passing by value) use const reference instead. Especially that in modern C++ and properly written code passing by value can be easilty more efficient than passing by reference. Commented Aug 22, 2022 at 21:19
  • 1
    @BorisBorais it is either a bad book or (which is more likely) you did not read it carefully - using const reference is the common practice to avoid copying significantly large object when passing it as an argument. You use lvlaue aka non-const reference only when you have intention to modify object which is passed to the function from outside scope. Commented Aug 22, 2022 at 21:48

2 Answers 2

6

friend std::ostream& operator<<(std::ostream& os, Vector& vec)

This signature doesn't accept rvalues, and this is why the error happens for your temporary result here:

std:: cout << x + y;

Change the second parameter into const Vector& vec or provide an overload with an r-value reference parameter.

friend std::ostream& operator<<(std::ostream& os, const Vector& vec);
Sign up to request clarification or add additional context in comments.

2 Comments

I'm always getting messed when it's up to rlvalues... thank you!!!
@BorisBorais no you are messed because you do not provide const correctness.
3

A temporary cannot bind to a non-const reference argument. You are missing const in at least two places. Most importantly here:

friend std::ostream& operator<<(std::ostream& os, const Vector& vec ) 
                                                // ^^ 

And there should a const overload of operator[]

2 Comments

It works perfectly fine , thank you! I should read more about temporaries and rlvalues...
@BorisBorais primarily you should make anything const that can be const.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.