Why overloading "<<" needs a const argument? [duplicate] - c++

This question already has an answer here:
c++ overloading stream operator, parameters by reference and anonymous instances
(1 answer)
Closed 3 years ago.
I have a class
class complex
{
[...]
complex operator+(const complex &c) const;
[...]
friend std::ostream &operator<<(std::ostream &os, const complex &c);
};
complex complex::operator+(const complex &c) const
{
complex result;
result.real_m = real_m + c.real_m;
result.imaginary_m = imaginary_m + c.imaginary_m;
return result;
}
std::ostream &operator<<(std::ostream &os, const complex &c)
{
os << "(" << c.real_m << "," << c.imaginary_m << "i)";
return os;
}
int main()
{
complex a(3.0, 4.0);
complex c(5.0, 8.0);
cout << "a is " << a << '\n';
cout << "a + c is " << a + c << '\n';
[...]
}
and, everything works fine, but if i remove const in std::ostream &operator<<(std::ostream &os, const complex &c) the cout << "a is " << a << '\n'; works fine but cout << "a + c is " << a + c << '\n'; doesn't, it say: No operator "<<" matches these operands. Thus, why this doesn't work without const ?

a + c is not an l-value, and so you cannot use a non-const reference on it.

Related

How does C++ compiler find closest type conversion when displaying my class object?

I write a class Fraction, and would like to display Fraction object with std::cout:
Fraction f(3, 5);
std::cout << f << std::endl;
I know overloading operator << can be used for this display purpose. But I can also overload operator type() function, and when only with operator double()(let type be double), I can still std::cout << f << std::endl.
Even more, I can also implement operator std::string(). But, when the mentioned 3 overloaded operator functions all exist, without explicitly type conversion, which one is called when doing std::cout << f << std::endl ? This really makes me curious, is this undefined behavior denpending on compiler implementation, or if there is some rule for scoring the closest/most suitable function to call?
To reproduce, use the following code:
#include <iostream>
#include <string>
class Fraction
{
public:
Fraction(int num, int den=1):
numerator(num), denominator(den) {}
operator double() const {
std::cout << "[operator double()]";
return numerator*1.0 / denominator;
}
operator std::string() const {
std::cout << "[operator std::string()]";
return std::to_string(numerator) + "/" + std::to_string(denominator);
}
private:
int numerator;
int denominator;
#ifdef OVERLOAD_STREAM_OP
friend std::ostream& operator << (std::ostream& os, const Fraction& frac);
#endif
};
#ifdef OVERLOAD_STREAM_OP
std::ostream& operator << (std::ostream& os, const Fraction& frac)
{
std::cout << "[operator <<]";
os << std::to_string(frac.numerator) << "/" << std::to_string(frac.denominator);
return os;
}
#endif
int main()
{
Fraction f(3, 5);
double d = 4 + f;
std::cout << "\n--- now let's print\n";
std::cout << "f: " << f << std::endl;
std::cout << "f: " << std::string(f) << std::endl;
std::cout << d << std::endl;
return 0;
}
The output on my ubuntu 20.04:
(base) zz#home% clang++ fraction.cpp
(base) zz#home% ./a.out
[operator double()]
--- now let's print
f: [operator double()]0.6
f: [operator std::string()]3/5
4.6

no operator "<<" matches these operands -- operand types are: std::ostream << Dual [duplicate]

This question already has answers here:
How can I use cout << myclass
(5 answers)
Closed 1 year ago.
I am getting trouble to output the object. I get an error in "cout << sum;" line. How can I print this Dual Number Object as D(float, float).
#include <iostream>
using namespace std;
class Dual{
public:
float val, eps;
Dual(float v, float e){
val = v;
eps = e;
}
Dual operator+(Dual const &obj) {
Dual res(0, 0);
res.val = val + obj.val;
res.eps = eps + obj.eps;
return res;
}
void print() const {
cout << "Dual(" << val << ", " << eps << endl;
}
};
int main(){
Dual d1(1, 2), d2(4, 5);
Dual sum = d1 + d2;
cout << sum;
return 0;
}
Change:
void print() const {
cout << "Dual(" << val << ", " << eps << endl;
}
to something like this:
friend std::ostream &operator<<(std::ostream &os, Dual const &d) {
os << "Dual(" << d.val << ", " << d.eps << ")";
return os;
}
... and off you go. Note that I've intentionally omitted printing a new-line as part of printing the Dual object. Oh, and when you want a new-line, just use "\n", not std::endl, which (at least IMO) was kind of a mistake and should be avoided in general.
You have not defined an operator<< for Dual, that is why you are getting the error. You do, however, have a print() method implemented, but you are not using it.
So, you can either:
simply change cout << sum; to sum.print();
int main(){
Dual d1(1, 2), d2(4, 5);
Dual sum = d1 + d2;
sum.print();
return 0;
}
otherwise, implement operator<<:
class Dual{
public:
float val, eps;
...
};
ostream& operator<<(ostream &os, Dual const &obj) {
os << "Dual(" << obj.val << ", " << obj.eps << endl;
return os;
}
If you still want to use print(), you should change it to take an ostream as input:
class Dual{
public:
float val, eps;
...
void print(ostream &os) const {
os << "Dual(" << val << ", " << eps << endl;
}
};
ostream& operator<<(ostream &os, Dual const &obj)
{
obj.print(os);
return os;
}
Then, you can use either of these:
cout << sum;
sum.print(cout);

Overloading ">>" and "<<" in C++ [duplicate]

This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 9 years ago.
Look at my code below. I made a class Vector2D. I overloaded the + operator and the * operator. In the main function I test these 2 overloaded operators. The only thing I want to add to this is the following: I want to overload the >> operator(?) so when I use >>, I can type in a vector. (so the x and the y component). Then I want to overload the << operator(?) so when I use <<, the program will return me my inputted vector.
#include <iostream>
using namespace std;
class Vector2D
{
public:
Vector2D();
Vector2D(double X = 0, double Y = 0)
{
x = X;
y = Y;
};
double x, y;
Vector2D operator+(const Vector2D &vect) const
{
return Vector2D(x + vect.x, y + vect.y);
}
double operator*(const Vector2D &vect) const
{
return (x * vect.x) + (y * vect.y);
}
};
int main()
{
cout << "Adding vector [10,10] by vector [5,5]" << endl;
Vector2D vec1(10, 10);
Vector2D vec2(5, 5);
Vector2D vec3 = vec1 + vec2;
cout << "Vector = " << "[" << vec3.x << "," << vec3.y << "]" << endl;
cout << "Dot product of vectors [5,5] and [10,10]:" << endl;
double dotp = vec1 * vec2;
cout << "Dot product: " << dotp << endl;
return 0;
}
The only problem is, I dont know how to do this. Could someone help me^.^?? Thanks in advance.
You need to declare these as friend functions to your Vector2D class (these may not meet your exact need and may require some formatting tweaking):
std::ostream& operator<<(std::ostream& os, const Vector2D& vec)
{
os << "[" << vec.x << "," << vec.y << "]";
return os;
}
std::istream& operator>>(std::istream& is, Vector2D& vec)
{
is >> vec.x >> vec.y;
return is;
}

C++ ostream << Operator

I have a Class that deals with Music Albums. The artists and albums are strings. It also has a collection (vector) of tracks called contents. Each track has a title and a duration.
This is my ostream <<:
ostream& operator<<(ostream& ostr, const Album& a){
ostr << "Album: " << a.getAlbumTitle() << ", ";
ostr << "Artist: " << a.getArtistName() << ", ";
ostr << "Contents: " << a.getContents() << ". "; //error thrown here
return ostr;
}
The << next to the a.getContents() is underlined and says: "Error: no operator "<<" matches these operands.
What am I missing out or doing wrong? Can you not use vectors in this way? or maybe its something I'm missing from my Track class?
Assuming Album::getContents() returns std::vector<Track>, you need to provide
std::ostream& operator<<(std::ostream& o, const Track& t);
and
std::ostream& operator<<(std::ostream& o, const std::vector<Track>& v);
where the latter can use the former. For example:
struct Track
{
int duration;
std::string title;
};
std::ostream& operator<<(std::ostream& o, const Track& t)
{
return o <<"Track[ " << t.title << ", " << t.duration << "]";
}
std::ostream& operator<<(std::ostream& o, const std::vector<Track>& v)
{
for (const auto& t : v) {
o << t << " ";
}
return o;
}
There's a C++03 demo here.
If Album::getContents() is about your vector and you just return the vector than ostream does not know how to write it, because there is no '<<' operator.
Just overload the '<<' operator for a vector and you are happy.

Using operator overloading in C++

class A
{
public:
ostream& operator<<(int string)
{
cout << "In Overloaded function1\n";
cout << string << endl;
}
};
main()
{
int temp1 = 5;
char str = 'c';
float p= 2.22;
A a;
(a<<temp1);
(a<<str);
(a<<p);
(a<<"value of p=" << 5);
}
I want the output to be: value of p=5
What changes should is do...and the function should accept all data type that is passed
There are 2 solutions.
First solution is to make it a template.
template <typename T>
ostream& operator<<(const T& input) const
{
cout << "In Overloaded function1\n";
return (cout << input << endl);
}
However, this will make the a << str and a << p print c and 2.22, which is different from your original code. that output 99 and 2.
The second solution is simply add an overloaded function for const char*:
ostream& operator<<(int string)
{
cout << "In Overloaded function1\n";
return (cout << string << endl);
}
ostream& operator<<(const char* string)
{
cout << "In Overloaded function1\n";
return (cout << string << endl);
}
This allows C strings and everything convertible to int to be A <<'ed, but that's all — it won't "accept all data type that is passed".
BTW, you have forgotten to return the ostream.