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);
}