C++ class template - c++

i am trying to get these class template in C++ to work. But there is always this error.
there is some kind of error in overloading but i don't know what.
i have tried overloading << operator using member function but there is still error.
#include <iostream>
using namespace std;
const int MAX = 10;
template <class T>
class mstack
{
T stk[MAX];
int top;
public:
mstack()
{
top = -1;
}
void push(T data)
{
if(top==MAX-1)
{
cout << endl << "stack is full" << endl;
}
else
{
top++;
stk[top] = data;
}
}
T pop()
{
if (top==-1)
{
cout << endl << "stack is empty" << endl;
return NULL;
}
else
{
T data = stk[top];
top--;
return data;
}
}
};
class mcomplex
{
float img, real;
public:
mcomplex()
{
real = 0;
img = 0;
}
mcomplex(float r, float i)
{
real = r;
img = i;
}
friend ostream& operator<< (ostream &o,mcomplex &c);
};
ostream& operator<< (ostream &o, mcomplex &c)
{
o << c.real << "\t" << c.img;
return o;
}
int main()
{
mcomplex c1(1.5f,2.5f), c2(3.5f,4.5f), c3(-1.5f,-0.6f);
mstack <mcomplex> s3;
s3.push(c1);
s3.push(c2);
s3.push(c3);
cout << endl << (s3.pop());
cout << endl << s3.pop();
cout << endl << s3.pop() << endl;
return 0;
}
compiler error is as following:
|76|error: no match for 'operator<<' (operand types are
'std::basic_ostream::__ostream_type {aka
std::basic_ostream}' and 'mcomplex')
|62|note: candidate: std::ostream& operator<<(std::ostream&,
mcomplex&)
|77|error: invalid initialization of non-const reference of type
'mcomplex&' from an rvalue of type 'mcomplex'
|78|error: no match for 'operator<<' (operand types are
'std::basic_ostream::__ostream_type {aka
std::basic_ostream}' and 'mcomplex')
can anyone show what is the error here?

Your pop() function is returning a temporary value. Taking non-const reference to this value doesn't make sense.

Although it depends on your purpose, you should throw something exception like as follows, not T():
if (top==-1)
{
throw std::runtime_error("stack is empty");
}
Demo

Got this thing to finally work.
corrections were.
ostream& operator<< (ostream &o,const mcomplex &c)
{
o << c.real << "\t" << c.img;
return o;
}
and
if (top==-1)
{
cout << endl << "stack is empty" << endl;
return T();
}

Related

why is this code not detecting << operator?

Please explain to me why this is not detecting the << operator.
I tried my best, even tried to overload << on both classes (which is not necessary).
#include<iostream>
using namespace std;
const int MAX = 10;
class Complex;
template<class t>
class stack {
private:
t stk[MAX];
int top;
public:
stack() { top = -1; }
void push(t data) {
if (top == MAX - 1)
cout << "Stack is full.";
else
stk[++top] = data;
}
t pop() {
if (top == -1) {
cout << "Stack is empty.";
return NULL;
}
else {
//return stk[top--];
t data = stk[top];
top--;
return data;
}
}
};
class Complex {
private:
float real, imag;
public:
Complex(float r = 0.0, float i = 0.0) { real = r; imag = i; }
friend ostream& operator << (ostream& s, Complex& c);
};
ostream& operator << (ostream& s, Complex& c) {
s << "(" << c.real << "," << c.imag << ")";
return s;
}
int main() {
stack<int> s1;
s1.push(10);
s1.push(20);
s1.push(30);
s1.push(40);
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
stack<float> s2;
s2.push(3.14f);
s2.push(4.14f);
s2.push(5.14f);
s2.push(6.14f);
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
Complex c1(1.5f, 2.5f), c2(1.5f, 2.5f), c3(1.5f, 2.5f), c4(1.5f, 2.5f);
//cout<<c1;
stack<Complex> s3;
s3.push(c1);
s3.push(c2);
s3.push(c3);
s3.push(c4);
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
return 0;
}
The function signature should be something like:
std::ostream& operator<<(std::ostream& os, const T& obj)
{
// write obj to stream
return os;
}
And the function pop can't return NULL since the type is not the same as t. Fixed code might like:
#include <iostream>
using namespace std;
const int MAX = 10;
class Complex;
template <class t>
class stack {
private:
t stk[MAX];
int top;
public:
stack() { top = -1; }
void push(t data) {
if (top == MAX - 1)
cout << "Stack is full.";
else
stk[++top] = data;
}
t pop() {
if (top == -1) {
cout << "Stack is empty.";
return {}; // May throw, or return std::optional here
} else {
// return stk[top--];
t data = stk[top];
top--;
return data;
}
}
};
class Complex {
private:
float real, imag;
public:
Complex(float r = 0.0, float i = 0.0) {
real = r;
imag = i;
}
friend ostream &operator<<(ostream &s, const Complex &c);
};
ostream &operator<<(ostream &s, const Complex &c) {
s << "(" << c.real << "," << c.imag << ")";
return s;
}
int main() {
stack<int> s1;
s1.push(10);
s1.push(20);
s1.push(30);
s1.push(40);
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
cout << s1.pop() << endl;
stack<float> s2;
s2.push(3.14f);
s2.push(4.14f);
s2.push(5.14f);
s2.push(6.14f);
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
cout << s2.pop() << endl;
Complex c1(1.5f, 2.5f), c2(1.5f, 2.5f), c3(1.5f, 2.5f), c4(1.5f, 2.5f);
// cout<<c1;
stack<Complex> s3;
s3.push(c1);
s3.push(c2);
s3.push(c3);
s3.push(c4);
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
cout << s3.pop() << endl;
return 0;
}
Online demo.
Related question: What are the basic rules and idioms for operator overloading?
It doesn't work because the second parameter should be a const reference
class Complex{
private:
float real,imag;
public:
Complex(float r=0.0,float i=0.0){
real=r;
imag=i;
}
friend ostream& operator<<(ostream& s, const Complex& c);
};
ostream& operator<<(ostream& s, const Complex& c) {
s<<"("<<c.real<<","<<c.imag<<")";
return s;
}
Reason:
The pop function returns an r-value. You can think of an r-value as a nameless object in memory (of course, there is more to it). You cannot put an r-value into an l-value reference. But for a const reference, it does not matter, since you are not going to modify it.
Solution 1:
friend ostream &operator<<(ostream &s, Complex &c); // accepts lvalue - c refers to some external Complex object.
friend ostream &operator<<(ostream &s, Complex &&c); // accepts rvalue - c becomes a normal local variable whose value is the passed rvalue.
Solution 2:
friend ostream &operator<<(ostream &s, const Complex &c); // accepts both

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

C++ Overloading <<. Error: no match for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'Poly')

Recently started to learn c++. Now i'm trying to overload << operator to print an instance of my class Poly representing polynomial. Here it is:
class Poly {
public:
Poly(unsigned int n);
Poly(Poly &obj);
int& operator[] (int index);
unsigned int degree();
long eval(int x);
Poly& operator= (Poly& p);
private:
int *coeffs;
unsigned int n;
};`
Implementations of methods work fine. I tried to define global function that overloads << operation :
std::ostream& operator << (std::ostream &os, Poly &p) {
for (int i = 0; i < p.degree()+1; i++){
if (i != 0)
os << " + " << p[i] << "x^" << i;
else
os << p[i];
}
os << std::endl;
return os;
}
but I get error in line where cout << p2 is in my main function:
int main() {
Poly *p1 = new Poly(2);
(*p1)[0] = 1;
(*p1)[1] = 1;
(*p1)[2] = 3;
cout<< p1->eval(2) << endl;
Poly p2(2);
p2 = (*p1);
cout << p2;
return 0;
}
If I declare this function in the class declaration as a friend everything works. Is that really necessary as this function doesn't access private members of the class? What do I do wrong? Iostream included everywhere.

std::setw for the whole operator<< of user-defined type

We know, that the std::setw() influence only on the next output.
So, what standard practice to align
the whole operator<< of user-defined type in table output:
class A
{
int i, j;
public:
friend ostream& opeartor<<(ostream& out, const A& a) {
return << "Data: [" << i << ", " << j << "]";
}
}
// ...
A[] as;
out << std::left;
for (unsigned i = 0; i < n; ++i)
out << std::setw(4) << i
<< std::setw(20) << as[i] // !!!
<< std::setw(20) << some_strings[i]
<< some_other_classes[i] << std::endl;
out << std::right;
Just add a setw() method to your class:
class A
{
int i, j;
mutable int width = -1;
public:
A& setw(int n) {
this->width = n;
return *this;
}
friend ostream& operator<<(ostream& out, const A& a);
};
And when you print it, if you want to align, simply use it:
int main() {
A as[5];
for (auto & a : as)
cout << a.setw(15) << endl;
}

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.