Overloaded ostream operator segmentation fault if no endl - c++

class foo {
public:
friend ostream& operator << (ostream &os, const foo &f);
foo(int n) : a(n) {}
private:
vector <int> a;
};
ostream& operator << (ostream &os, const foo &f) {
for (int i = 0; i < f.a.size(); ++i)
os << f.a[i] << " ";
os << endl; // why is this line a must?
}
int main(void) {
foo f(2);
cout << f << endl;
return 0;
}
In the above code, if the marked line is removed, there will be a segment fault error, can someone explain why?

ostream& operator << (ostream &os, const foo &f) {
for (int i = 0; i < f.a.size(); ++i)
os << f.a[i] << " ";
os << endl; // why is this line a must?
}
is not manadatory. The segfault is caused because you are not returning os
ostream& operator << (ostream &os, const foo &f) {
for (int i = 0; i < f.a.size(); ++i)
os << f.a[i] << " ";
return os; // Here
}
it is undefined behavior if you don't return the ostream. The endl is flushing your os here. That's why it seems like it is working.
EDIT: Why it is working in this case according to Bo Persson
The os << endl; is another operator call that actually returns os by
placing it "where a return value is expected" (likely a register).
When the code returns another level to main, the reference to os is
still there

Related

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

How to overload the operator << inside a structure

I just want to print the two values of my structure, but can't compile my code - I get: no operator “<<” matches these operands.
#include <iostream>
using namespace std;
struct SCoor
{
int i, j;
bool operator == (const SCoor & tmp) const
{
return (i == tmp.i && j == tmp.j);
}
bool operator < (const SCoor & tmp) const
{
return (i < tmp.i || (i == tmp.i && j < tmp.j));
}
ostream& operator << (ostream &o) {
return o << i << " " << j;
}
};
int main()
{
SCoor tmp = { 3, 3 };
cout << tmp;
return 0;
}
How do I have to overload the operator "<<"?
You overload the << operator as a member function if you want your structure to be on the left hand side of the expression. So:
struct SCoor
{
// ...
SCoor& operator << (Stuff const& s) {
// ...
return *this;
}
};
// ...
Stuff stuff;
SCoor scoor;
scoor << s; // insert s into my SCoor
If you want to make your struct the right hand side of the << expression you have to define a standalone function:
std::ostream& operator<<(std::ostream& os, SCoor const& scoor)
{
return os << scoor.i << " " << scoor.j;
}
However it is quite common to make the external function a friend function and to define it in the struct definition:
struct SCoor
{
// ...
friend std::ostream& operator<<(std::ostream& os, SCoor const& scoor)
{
return os << scoor.i << " " << scoor.j;
}
};
// ...
SCoor scoor;
std::cout << scoor << '\n';
But it is not a member of your struct, it is just defined inside its definition for convenience.

Why can't I access members declared in my class while overloading "<<" operator?

i have a little issue here that i can't handle. So, i declared my class Sir like this:
typedef unsigned int Uint;
typedef vector<Uint> TVint;
typedef vector<Uint>::const_iterator TIterator;
class Sir
{
protected:
Uint _count;
TVint _elements;
public:
...
friend std::ostream& operator << (std::ostream &out, const Sir &sir)
{
for(size_t i = 0; i < sir._count; i++)
{
out<<"[" << i << "]" << " " << sir._elemente[i]<<endl;
}
}
};
It says that cannot access protected member declared in class. What am I missing??
There is a typo, you should use _elements in the overloaded << instead of _elemente. and you should return something from that method:
friend std::ostream& operator << (std::ostream &out, const Sir &sir)
{
for(size_t i = 0; i < sir._count; i++)
{
out<<"[" << i << "]" << " " << sir._elements[i] <<endl;
//^^^^^^^^^^^^^^^^
}
return out;
//^^^^^^^^^^^
}
Live code

C++ operator overload doesnt work

I have a question about operators and how to overload them. There is an example of code and I'm overloading operator<< but it doesn't work. There is class that I use:
class CStudent{ //class for students and their attributes
int m_id;
int m_age;
float m_studyAverage;
public:
CStudent(int initId, int initAge, float initStudyAverage): m_id(initId), m_age(initAge), m_studyAverage(initStudyAverage){}
int changeId(int newId){
m_id = newId;
return m_id;
}
int increaseAge(){
m_age++;
return m_age;
}
float changeStudyAverage(float value){
m_studyAverage += value;
return m_studyAverage;
}
void printDetails(){
cout << m_id << endl;
cout << m_age << endl;
cout << m_studyAverage << endl;
}
friend ostream operator<< (ostream stream, const CStudent student);
};
Overload:
ostream operator<< (ostream stream, const CStudent student){
stream << student.m_id << endl;
stream << student.m_age << endl;
stream << student.m_studyAverage << endl;
return stream;
}
And there is main method:
int main(){
CStudent peter(1564212,20,1.1);
CStudent carl(154624,24,2.6);
cout << "Before the change" << endl;
peter.printDetails();
cout << carl;
peter.increaseAge();
peter.changeStudyAverage(0.3);
carl.changeId(221783);
carl.changeStudyAverage(-1.1);
cout << "After the change" << endl;
peter.printDetails();
cout << carl;
return 0;
}
Where is the problem?
The problem here is you need to learn what references are and the difference between std::ostream and std::ostream& is.
std::ostream& operator<< (std::ostream& stream, const CStudent& student)

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.