I am trying to revive some old software but the problem is that the software was written in 2003 with MC and windows Iostream Header files have changed from that times iostream.h to iostream.
So this software had a 3D matrix Library which had function something like this
friend ostream& operator<< (ostream&, const CMatrix3D<T>&);
this function was no more compatable with iostream so I changed it to:
friend bool operator<< (std::ostream&, const CMatrix3D<T>&);
but now at one place where this function was previously called as:
friend ostream& operator << (ostream& os, block* bl)
{
vec_3d p1 = bl->points[0]->value();
vec_3d p2 = bl->points[6]->value();
os << "Diagonal points: " << p1 << " " << p2;
return os;
}
and then I changed it to:
friend bool operator << (std::ostream& os, block* bl)
{
vec_3d p1 = bl->points[0]->value();
vec_3d p2 = bl->points[6]->value();
os << "Diagonal points: " << p1 << " " << p2;
return os;
}
giving me these errors:
error C2297: '<<' : illegal, right operand has type 'const char [2]'
error C2678: binary '<<' : no operator found which takes a left-hand
operand of type 'int' (or there is no acceptable conversion)
Can someone suggest me a way out?
The reason that that the operator<< on ostreams has a return type of ostream& is so that it can be chained, to call as shown in your example implementations:
os << "Diagonal points: " << p1 << " " << p2;
This is the standard behavior of that operator, and a lot of code will rely on it, so it's a bad idea to have it return something else such as the bool that you changed it to. It should always return std::ostream&.
That should fix at least some of your problems. It is not clear without seeing the rest of your code, and knowing exactly which line the compiler is complaining about, whether that is all of the problem or not.
To remove whitespace from an input stream these days, you use the std::ws input manipulator.
i.e.
fp >> ws;
MSDN Reference for std::ws.
Related
Not able to understand why this is failing?
int *p = new int(10);
std::unique_ptr<int> ptr(p);
// Below line gives compilation error.
std::cout << "Value of ptr " << ptr << std::endl;
// Below line works well.
std::cout << "Value pointed ptr " << *ptr << std::endl;
std::cout << "Value of ptr->get() " << ptr.get() << std::endl;
I understand it this way:
Say address of p is 100, address of new allocated memory is 200.
p new allocated memory
---------- ---------
200 10
---------- ---------
100 200
ptr
----------
200
----------
300
In above depiction, unique_ptr is pointing to newly allocated memory itself, avoiding 'p'. So, should not printing 'ptr' give me 200?
std::unique_ptr<int> ptr(p);
// Below line gives compilation error.
std::cout << "Value of ptr " << ptr << std::endl;
To make it possible to use the usual << syntax to print an object of some class using cout, there must be a proper overload of operator<< implemented.
For example, if you have a class X, if you want to enable the cout << x syntax, you can overload operator<< like this:
#include <ostream> // for std::ostream
std::ostream& operator<<(std::ostream& os, const X& x)
{
// Implement your output logic for 'x'
...
return os;
}
The C++ standard library designers chose not to implement such an overload for std::unique_ptr; this is why you get the compilation error when you try to use << with instances of unique_ptrs.
So, should not printing 'ptr' give me 200?
It should, if the standard library specified std::unique_ptr should be streamable into standard streams. In other words, that an overload of operator << for std::unique_ptr should exist.
However, the standard specifies no such thing, and therefore streaming a unique_ptr results in a compilation error (no operator << accepts it). The solution is as you have found: if you need to stream the pointer, get the pointer:
stream << ptr.get()
The problem is that prior to C++20, there is no overloaded operator<< for unique_ptr.
But starting from C++20, there is, which can be seen from unique_ptr:
template< class CharT, class Traits, class Y, class D >
std::basic_ostream<CharT, Traits>& operator<<( std::basic_ostream<CharT, Traits>& os, const std::unique_ptr<Y, D>& p );
Inserts the value of the pointer managed by p into the output stream os.
Equivalent to os << p.get().
This means, std::cout << ptr; will work in C++20(&onwards).
Demo
I wrote a simple binary tree class in C++ and want to add an output operator to it. My first attempt was:
ostream& operator<<(ostream& out, const Tree& tree) {
out << tree.myData;
if (tree.myLeft)
out << "(" << (*tree.myLeft) << ")";
if (tree.myRight)
out << "[" << (*tree.myRight) << "]";
return out;
}
(where myLeft and myRight are pointers to left and right child of the current tree, respectively). This works correctly, however, it is not sufficiently cool, since it spans several lines and requires to write "out << " several times.
As an attempt to create a one-line operator, I wrote this:
ostream& operator<<(ostream& out, const Tree& tree) {
return (out << tree.myData
<< "(" << (tree.myLeft? *tree.myLeft: "") << ")"
<< "[" << (tree.myRight? *tree.myRight: "") << "]");
}
But, this generates an error:
incompatible operand types ('Tree' and 'const char [1]')
So I tried this:
ostream& operator<<(ostream& out, const Tree& tree) {
return (&tree?
out << tree.myData
<< "(" << *(tree.myLeft) << ")"
<< "[" << *(tree.myRight) << "]":
out);
}
This works on my computer, but generates a warning implying that this is undefined behavior:
Reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to always convert to true [-Wundefined-bool-conversion]
QUESTION: Is there a way to write this output operator in a simple single statement?
A simple and elegant solution is to redesign your tree to work without null pointers. Instead, replace current uses of null pointers with pointers to a sentinel tree node which has behaviour consistent with an empty tree.
Then you can rewrite your output stream operator as follows:
ostream& operator<<(ostream& out, const Tree& tree) {
if (&tree == &Tree::NULL_TREE_SENTINEL) return out;
return out << tree.myData
<< "(" << *tree.myLeft << ")"
<< "[" << *tree.myRight << "]";
}
(This assumes a corresponding static member inside Tree, to which the sentinels are pointers, like singletons.)
Alternatively, the sentinel tree node could be an instance of a subclass of Tree with this behaviour. This is sometimes known as the null object pattern. However, it requires dynamic dispatch (i.e. runtime polymorphism via virtual member functions) to work.
Apart from this you don’t quite diagnose the problem with your second code correctly:
This works on my computer
It appears to work but doesn’t actually. I don’t know under what exact circumstances that code will actually do something nasty. But just to be clear, your code is illegal due to the sub-expressions *(tree.myLeft) and *(tree.myRight): these expressions are dereferencing null pointers, and this is never legal. The warning message you’re receiving about the &tree test is merely a symptom of that prior error.
This question already has answers here:
Why we need to return reference to istream/ostream while overloading >> and << operators?
(4 answers)
Closed 5 years ago.
//using namespace std;
Here's the following piece of code
ostream& write(ostream& os) const {
os << getRe() << "j " << getIm();
return os;
}
This is a member function in a class representing complex numbers ("PComplex), which is derived from an abstract class ("Serializable"). (Implementation of pure virtual function).
My main question is why do we need to return a reference to an ostream object? Why not void?
Returning an ostream& object allows us to chain a bunch of operators togeather.
Consider this statement
cout << "Hello " << "World";
This is actually two calls to ostream& operator<<(ostream& os, const char* c). If we consider the order of execution, we get:
(cout << "Hello ") << "World";
This function accepts cout on the left and "Hello " on the right. It prints the contents of the right hand-side to the console, then it returns cout. We we consider what's left after the first step we get this:
(cout) << "World";
Now we take the brackets away and get:
cout << "World;
This one is much easier to deal with. Now we call the function again to print `"World" and return the cout again, which we will simply not do anything with.
If we returned void instead of ostream&, then (cout << "Hello ") would reduce to (void). That would leave us with:
(void) << "World";
This doesn't match any overloads and so we would then get an error. While the (cout << "Hello ") would still work, we wouldn't be able to chain << "World" on the same line.
so I am coding my c++ homework assignment and there is a final part where he wants us to Replace the formatted output method (toString) with an overloaded output/insertion operator. TO be 100% honest I have no idea what he means by this. I've searched around a bit and found example codes using an overloaded insertion operator, but can't seem to find how to incorporate it into my code. Though I think I may be looking in the wrong place. My toString is as follows:
string Movie::toString() const {
ostringstream oS;
oS << "\n\n====================== Movie Information\n"
<< "\n Movie Title:\t" << title << " (" << releaseYear << ")"
<< "\n US Rank & Box Office:\t" << usRank << "\t$" << usBoxOffice
<< "\nNon-US Rank & Box Office:\t" << nonUSRank << "\t$" << nonUSBoxOffice
<< "\n World Rank & Box Office:\t" << worldRank << "\t$" << worldBoxOffice
<< "\n";
return oS.str();
}
Like I mentioned I'm not sure what "overloaded" means, so If for some reason this isn't enough information for you to help me with the problem directly, then can you give me a brief description of what he may mean by replacing the current output with an overloaded output operator. Thank You
edit: This is the next question I have. https://stackoverflow.com/questions/14924621/c-overloaded-output-operator-cont
To overload a function means to provide other functions with the same name but different parameter types. Operators can also be overloaded. Many operators have a corresponding function that can be overloaded called operator??, where ?? is the operator itself. For example if you have two objects x and y of class type T, you could overload operator+. Overloading an operator allows you to give some meaning to using that operator with the type. So now you could do x + y.
The stream insertion operator is <<. It's what you use when you do std::cin << "hello"; - it inserts into the stream. This operator can also be overloaded, just as + was overloaded above. The function you need to overload is called operator<<.
There are two ways to overload a binary operator like << (binary because it takes two operands, one on the left side and one on the right, left << right). One is to make it a member of the type of left and give it a single parameter of the type of right. The other is to make it a non-member function with two parameters, one the type of left and the other the type of right. Since the type of your left will be std::ostream, you can't modify the class (because it's provided by the standard), so you'll have to go with option two.
So your free function needs to look something like this:
std::ostream& operator<<(std::ostream& os, const Movie& movie) {
// Insert everything you want into `os`
return os;
}
Now this function will be called whenever you do << with an std::ostream on the left and a Movie on the right.
I think your task is meant to be writing an overloaded operator << which allows you to write the string representation of your object to an output stream:
std::ostream& operator <<(std::ostream& os, const Movie& movie) {
os << "\n\n====================== Movie Information\n"
<< "\n Movie Title:\t" << movie.title << " (" << movie.releaseYear << ")"
<< "\n US Rank & Box Office:\t" << movie.usRank << "\t$" << movie.usBoxOffice
<< "\nNon-US Rank & Box Office:\t" << movie.nonUSRank << "\t$" << movie.nonUSBoxOffice
<< "\n World Rank & Box Office:\t" << movie.worldRank << "\t$" << movie.worldBoxOffice
<< "\n";
return os;
}
And you use this operator as you could do with built-in types:
Movie m;
// Do something with m
cout << m; // Write m to the standard output
I want to overload << operator in a Line class so I can print an object using cout like this:
cout << myLineObject << endl;
but this is not working:
class Line{
public:
float m;
float b;
string operator << (Line &line){return ("y = " + line.m + "x + " + line.b);};
};
I get:
Invalid operands of types 'const char [5]' and 'float' to binary 'operator+'
I also tried with stringstream but I get even more errors. What is the correct way of doing this?
Thanks ;)
The correct way is listed everywhere overloading << is discussed, and you've managed to miss pretty much all of it.
The standard declaration is ostream & operator<<(ostream & s, const & Line l); It cannot be a member function, and it needs to return a reference to the ostream so that you can chain << as normal.
The definition, in your case, would be something like
ostream & operator<<(ostream & s, const & Line l)
{
return s << "y = " << l.m << "x + " << l.b;
}
Note that you return the incoming ostream, and print what you like using the << operator rather than using the + operator. It's pretty simple if you follow this
form.
In this case, the data members are public (which is not a good idea in general),
so there's no access problems. If you need to get inaccessible values (because
they're private and not exposed in the public interface), you'll need to declare
the operator to be a friend in the class definition.
operator<< has to be a non-member function, since the stream is the left-hand argument. In your case, since the data members are public, it can be implemented outside the class:
std::ostream& operator<<(std::ostream& stream, const Line& line)
{
return stream << "y = " << line.m << " x = " << line.b;
}
Googled this one, looks fine:
Overloading <<
Basically, when overloading << operator for IO, your function should look like this:
friend ostream& operator<<(ostream& output, const YourClassHere& p);
Notice, that operator<< is not a class member, but a external function (which can be friend if you need it to be). Such function should use output to write to it and then return it, so you can chain it.
The error here is nothing to do with the operator overloading, though once resolved you may have more questions on that. This error happens because there is no operator+ defined that takes arguments of const char[5] and float. Since you are trying to concatenate the string forms of those four args
"y = " + line.m + "x + " + line.b
you have to do this in a way the compiler can understand e.g.
ostringstream concat;
concat << string("y = ") << line.m << string("x + ") << line.b;
return concat.str();
Once you get past this, you can work on your << overloading logic.
You can do this way:
class Line{
public:
float m;
float b;
friend ostream& operator<< (ostream& out, Line& object) {
out << object.m << endl;
out << object.b << endl;
return out;
}
};
Then you can do:
cout << your_Line_object << endl;
Other have explained the correct way. I figured I'd mention what you are doing wrong.
You define an operator which takes two Line objects:
Line a;
Line b;
string c = a << b;
// c would have the string values for line b
// the values of line a would be ignored.
Of course, that's not the error you are seeing. That's caused by the line "y = " + line.m. "y = " is a char[5]. amd line.m is a float, and there is no operator+ which takes those two (This ain't Basic -- or C#).
The problem is that C++ has no easy way to "add" non-string values to a string. Which is why we use the convention of cout <<.