Why overloaded operator << works sometimes but other times doesn't - c++

I don't know why cout << da << '\n' works fine,but std::cout << next_Monday(da) << '\n' went wrong. Why the direct Date object can output, but the return Date can't.
Why overloaded operator << works sometimes but other times doesn't.
here is my code..
#include <iostream>
#include <stdlib.h>
struct Date {
unsigned day_: 5;
unsigned month_ : 4;
int year_: 15;
};
std::ostream& operator<<(std::ostream& out,Date& b)
{
out << b.month_ << '/' << b.day_ << '/' << b.year_;
return out;
}
std::istream& operator>>(std::istream& in,Date& b);
Date next_Monday(Date const &d);
int main()
{
Date da;
std::cin >> da;
std::cout << da << '\n';
std::cout << next_Monday(da) << '\n';
return 0;
}
this is what clang said: (I use g++ to invoke)
excercise19DateManipulate.cpp:114:18: error: invalid operands to binary
expression ('ostream' (aka 'basic_ostream<char>') and 'Date')
std::cout<< next_Monday(da) <<'\n';
~~~~~~~~^ ~~~~~~~~~~~~~~~

Because you can't bind a temporary to a non-const lvalue reference. Change the operator to take a const reference:
std::ostream& operator<<(std::ostream& out, const Date& b)

You never defined the "next_Monday()" function as far as I can see, you only declared it.

Related

How does the program 'remember' the temporary object?

#include <iostream>
using namespace std;
class A {
public:
int first;
int last;
A(int x = 0, int y = 0):first(x), last(y){}
A(A&a) { cout << "c ctor \n"; }
};
ostream& operator<<(ostream& os, A b) {
os << "first:" << b.first << " last:" << b.last << endl;
return os;
}
istream& operator>>(istream& is, A a) {
is >> a.first >> a.last;
return is;
}
int main()
{
A i;
cout << "enter first and last: \n";
cin >> i;
cout << i;
system("pause");
return 0;
}
A a is a new A object in the >> overload, and if we enter 6 4 into it, the program will remember it in the << overload function, and print what we entered into it. Can someone explain why? Thanks.
This is a wrong statement relative to your presented code because the operator >> deals with a copy of the original object used as an argument of the operator.
The operator should be declared like
istream& operator>>(istream& is, A &a) {
is >> a.first >> a.last;
return is;
}
And moreover the copy constructor does not copies data members.
So the program has undefined behavior. For example running it using clang HEAD 11.0.0 you can get the following result
prog.cc:8:9: warning: unused parameter 'a' [-Wunused-parameter]
A(A&a) { cout << "c ctor \n"; }
^
1 warning generated.
enter first and last:
c ctor
c ctor
first:4202496 last:0
That is the program outputs the variables first and last with indeterminate values because the data members of the created object b in the operator << were not initialized.

Error: No match for 'operator>>' Overloading istream operator

learning C++ right now and ran into a bit of a problem. While trying to complete an example and make sure it works ran into the error:
error: no match for 'operator>>' (operand types are 'std::istream' and 'const int')
conversion of argument 1 would be ill-formed
Here is my code,
#include <iostream>
#include <sstream>
#include <cstdlib>
using namespace std;
class Distance {
private:
int feet;
int inches;
public:
Distance() {
feet = 0;
inches = 0;
}
Distance(int f, int i) {
feet = f;
inches = i;
}
friend ostream &operator<<( ostream &output, const Distance &D ) {
output << D.feet << "\'" << D.inches << "\"" << endl;
return output;
}
friend istream &operator>>( istream &input, const Distance &D ) {
input >> D.feet >> D.inches;
return input;
}
};
int main() {
Distance D1(11,10), D2(5,11), D3;
cin >> D3;
cout << "First Distance : " << D1 << endl;
cout << "Second Distance : " << D2 << endl;
cout << "Third Distance : " << D3 << endl;
return 0;
}
Trying to overload the istream and ostream operators, but running into problems with the istream operator >>.
First thought to convert the variable D.feet and D.inches to char* but that doesn't seem right considering that I have to feed an int into the variables. Not sure what is wrong with my code, can anyone help?
Remove const in >> operator overload.
Your Distance is const'd.
[SOLVED]
Figured out the problem in this was that the 'const' in
ostream &operator>>( istream &input , const Distance &D )
Can't explain the actual processes and why this is a conflict, but perhaps somebody else could please explain? I'd really like to know it in depth.
Thanks!

Is it possible to have different operator<<() overloads to write to a file and std::cout?

Edit: Definition of class TF:
class TF {
std::vector<V4f> waypoints;
std::vector<int> densityWaypoints;
public:
std::size_t size() const { return waypoints.size(); }
friend std::ostream& operator<<(std::ostream& str, const TF& tf);
friend std::fstream& operator<<(std::fstream& str, const TF& tf);
// methods here
};
The question may steam from the fact that I don't understand streams, so that's probably a precondition.
Is it somehow possible to overload operator<<(std::ostream, T) so that when invoked in order to display the data structure on screen, it uses one overload, and when the data structure is written to a file, another one is used? Something like this probably:
std::ostream& operator<<(std::ostream& str, const TF& tf) {
for (std::size_t i = 0; i != tf.waypoints.size(); ++i) {
str << " { "
<< tf.densityWaypoints[i] << " : "
<< tf.waypoints[i][3] << " : "
<< tf.waypoints[i][0] << " , "
<< tf.waypoints[i][1] << " , "
<< tf.waypoints[i][2]
<< " } ";
}
str << "\n";
return str;
}
std::fstream& operator<<(std::fstream& str, const TF& tf) {
str << (int)tf.size();
for (std::size_t i = 0; i != tf.waypoints.size(); ++i) {
str << tf.densityWaypoints[i]
<< tf.waypoints[i][0]
<< tf.waypoints[i][1]
<< tf.waypoints[i][2]
<< tf.waypoints[i][3];
}
This doesn't compile with a strange error (I may be tired):
error: no match for ‘operator<<’ (operand types are ‘std::fstream {aka std::basic_fstream}’ and ‘int’)
The error occurs when I add the second operator<<() overload. The first one works fine. Tried both std::ofstream and std::fstream to the same result.
But I'm not sure if it's going to work either. Sure it's possible to define a function like int writeTF(std:fstream& str, const TF&tf), but that doesn't look C++ enough to me, not to mention the strange error that will potentially appear here, too.
I've seen code comparing the ostream's address to that of cout. I have mixed feelings about it, but it certainly worked:
std::ostream& operator<<(std::ostream& o, Foo const&)
{
if(&o == &std::cout) {
return o << "cout";
} else {
return o << "not_cout";
}
}
demo
Note that cout outputs to standard output, it's not the same thing as "the screen".

issue with ostream and << overloading

I have this printing line of code:
std::cout << *it << std::endl;
now, since 'it' is a complex type I need to write my own '<<' operator.
this is my function:
friend ostream& operator<<(ostream& os, const Node& n ){
return os << n.key << ':' << n.value;
}
I get an error "type ostream could not be resolved"
I've tried adding std:: before "ostream" but that doesn't help. I'm not sure what else I can try.
You need to #include <ostream> (<iostream> is not be enough if you're using C++03).
If you've done that, and used the std:: qualifying prefix, then there's something you're not telling us or you're compiling the wrong file!
#include <ostream> // for std::ostream
#include <iostream> // for std::cout
struct Node
{
int key;
int value;
};
std::ostream& operator<<(std::ostream& os, const Node& n) {
return os << n.key << ':' << n.value;
}
int main()
{
Node n = {3, 5};
std::cout << n << '\n';
}
// Output: `3:5`
Live demo

C++ - ostream, friends and namespaces

Everything was fine until I moved my objects to a namespace. And now the compiler claims that my Color attributes are private.
I thought the whole point of friends was to share encapsulated information with those a class befriends.
Color.h
friend ostream & operator << (ostream& output, const st::Color& color);
Color.cpp:
ostream & operator <<(ostream& output, const st::Color& color) {
output << "Colors:\nalpha\t: " << color.a << "\nred\t: " << color.r << "\ngreen\t: " << color.g
<< "\nblue\t: " << color.b << "\nvalue\t: " << color.color();
return output;
}
error:
Color.h||In function 'std::ostream& operator<<(std::ostream&, const st::Color&)':|
Color.h|52|error: 'unsigned char st::Color::a' is private|
Color.cpp|15|error: within this context|
Color.h|49|error: 'unsigned char st::Color::r' is private|
Color.cpp|15|error: within this context|
Color.h|51|error: 'unsigned char st::Color::g' is private|
Color.cpp|15|error: within this context|
Color.h|50|error: 'unsigned char st::Color::b' is private|
Color.cpp|16|error: within this context|
||=== Build finished: 8 errors, 0 warnings (0 minutes, 1 seconds) ===|
So what is the deal?
I'm using Code::Blocks as my IDE. And it won't even show any properties or methods when I use the dot operator on the "color" parameter. This is obviously a sign of something going wrong...somewhere.
I've taken the friend operator overloading out and it compiles just fine. No error elsewhere.
What gives?
It's declared as follows:
namespace st{
class Color {
friend ostream & operator << (ostream& output, const st::Color& color);
public:
....
private:
.....
};
};
Edit:
In my CPP I've now done this:
namespace st{
ostream & st::operator <<(ostream& output, const st::Color& color) {
output << "Colors:\nalpha\t: " << color.a << "\nred\t: " << color.r << "\ngreen\t: " << color.g
<< "\nblue\t: " << color.b << "\nvalue\t: " << color.color();
return output;
}
}
st::Color::Color() {
reset();
}
st::Color::Color(const Color& orig) {
a = orig.a;
r = orig.r;
g = orig.g;
b = orig.b;
}
void st::Color::reset() {
a = 0;
r = 0;
g = 0;
b = 0;
}
... etc
}
No compile errors, but is it normal for such a situation to use the namespace again in the header? Or is this completely off from what I should be doing?
Edit:
#Rob thanks for your input as well!
You need to declare and define your operators in the same namespace as the object as well. They will still be found through Argument-Dependent-Lookup.
A usual implementation will look like this:
/// header file
namespace foo {
class A
{
public:
A();
private:
int x_;
friend std::ostream& operator<<(std::ostream& o, const A& a);
};
std::ostream& operator<<(std::ostream& o, const A& a);
} // foo
// cpp file
namespace foo {
A::A() : x_(23) {}
std::ostream& operator<<(std::ostream& o, const A& a){
return o << "A: " << a.x_;
}
} // foo
int main()
{
foo::A a;
std::cout << a << std::endl;
return 0;
}
Edit
It seems that you are not declarin your operator<< in the namespace and are also defining it outside of the namespace. I've adjusted the code.
You need to qualify your operator with the namespace as well. It is a function signature declared in the name space so to access its symbol you need to prefix it with the namespace.
Try it like this:
namespace st {
ostream & operator <<(ostream& output, const Color & color) {
output << "Colors:\nalpha\t: " << color.a
<< "\nred\t: " << color.r
<< "\ngreen\t: " << color.g
<< "\nblue\t: " << color.b
<< "\nvalue\t: " << color.color();
return output;
}
}