Home > Blockchain >  Overload << operator
Overload << operator

Time:01-11

I have a custom vector class (vector as in mathematical sense - thats why there is a weird name Multivector.) I want to overload the << function, as in many examples online (including StackOverflow.) It does not work - VSCode does not connect friend declaration and <<operator definition. I think that is the major problem but I cannot find the flaw.

The code compiles. Executable outputs nothing.

// Utils.hpp

#include <vector>
#include <string>

class Multivector {
    public:
        // init with zeros
        Multivector(int dimension);
        Multivector(std::vector<double> values);

        int getSize() const;
        double get(int i) const;
        void   set(int i, float value);

        // no idea why this does not work
        // displaying the contents of Multivector on an outstream
        friend std::ostream& operator<<(std::ostream& os, const Multivector& mv);

    private: 
        std::vector<double> m_Values;
        int m_Size;
};
// Utils.cpp

#include <iomanip>
#include <algorithm>

#include "Utils.hpp"

Multivector::Multivector(int dim) { 
    m_Values = std::vector<double>(dim);
}

Multivector::Multivector(std::vector<double> v) : m_Values(v) { }

int Multivector::getSize() const {
    return m_Size;
}

double Multivector::get(int i) const {
    return m_Values[i];
}

void Multivector::set(int i, double value) {
    m_Values[i] = value;
}

std::ostream &operator<<(std::ostream& os, const Multivector& mv) {
    unsigned int longest = 0;
    for (int i = 0; i < mv.getSize(); i  ) {
        auto value = mv.get(i);
        auto string_value = std::to_string(value);
        longest = std::max(longest, string_value.length());
    }

    os << "(";
    for (int i = 0; i < mv.getSize() - 1; i  ) {
        os << std::right << std::setw(longest) << std::setfill(' ') << mv.get(i) << ",";
    }
    os << mv.get(mv.getSize()-1);
    os << ")";
    return os;
}

// main.cpp

#include <iostream>

#include "Utils.hpp"

int main() {

    Multivector mv(5);
    mv.set(3, 2.4);
    std::cout << mv;

    return 0;
}   

CodePudding user response:

When I compile this I get a couple of issues:

The definition of set is not the same as declaration:

In class:

// In Class
void   set(int i, float value);

// Definition
void Multivector::set(int i, double value)
                             ^^^^^^.  Fix this

Using std::max() the types need to be the same:

 longest = std::max(longest, string_value.length());
                    unsigned int, std::size_t

These are not always the same.

The biggest issue is that:

  m_Size. Is never set.
          So this is an undefined value.
          So returning it as the result of getSize() returns
          a meaningless value.

Looking at your getSize() function:

// Why not return the value of the vector (m_Values)?
int Multivector::getSize() const {
    return m_Size;
}

Seems like m_Size is a useless variable. Rememove it.

Then in the class I define the print as:

 std::ostream& print(std::ostream& s = std::cout) const;

I like to simplify the use of the operator<< by calling a print method in the object. This makes the defintion of the stream operator trivial enough to be done in place in the class.

 friend std::ostream& operator<<(std::ostream& s, Object const& o)
 {
     return o.print(s);
 }
  • Related