Difficulty in ostream - c++

ostream& operator<<(ostream& os, const PT& p)
{
os << "(" << p.x << "," << p.y << ")";
}
PT is a structure and x , y are its members.
Can someone please explain what exactly the above line does. Can't the desired text be printed using cout?
I came across this snippet of code from this site.

It's a custom overload for operator<<.
It means you can do this:
PT p = ...;
std::cout << p << "\n";
or this:
PT p = ...;
std::stringstream ss;
ss << p << "\n";
std::cout << ss;
or lots of other useful stuff.
However, it should be noted that the code you quoted won't work properly. It needs to return os.

This provides a method of outputting the PT. Now, you can use this:
PT p;
std::cout << p;
This gets translated into a call of
operator<< (std::cout, p);
That matches your overload, so it works, printing the x and y values in brackets with less effort on the user's part. In fact, it doesn't have to be cout. It can be anything that "is" a std::ostream. There are quite a few things that inherit from it, meaning they are std::ostreams as well, and so this works with them too. std::ofstream, for file I/O, is one example.
One thing that the sample you found doesn't do, but should, though, is return os;. Without doing that, you can't say std::cout << p << '\n'; because the result of printing p will not return cout for you to use to print the newline.

It allows the << operator to append the PT object to the stream. It seems the object has elements x and y that are added with a comma separator.

This operator << overloading for outputing object of PT class .
Here:
ostream& operator<<(ostream& os, const PT& p)
First param is for output stream where p will be appended.
It returns reference to os for chaining like this:
cout << pt << " it was pt" << endl;

Related

C++ indent overloaded ostream operator

Let's say Ì have some class and added output functionality by overloading the left-shift operator:
struct Foo
{
int i = 1;
std::string s = "hello";
};
auto& operator<<(std::ostream& os, Foo const& foo)
{
os<<foo.i<<"\n";
os<<foo.s<<"\n";
return os;
}
What is a good way to indent the output?
Example: If I write
std::cout<<" "<<Foo{}<<std::endl;
the output is:
1
hello
Obviously, hello is not indented. Is there an easy way to indent the whole output (and not just the first element)?
You're serializing the Foo object right? So logically the serialized string of Foo is an implementation detail of Foo. You could write your own stream class or something along those lines but that is overengineering the problem.
auto& operator<<(std::ostream& os, Foo const& foo)
{
auto s = "\t" + std::to_string(foo.i) + "\n"
"\t" + foo.s;
return (os << s);
}
int main()
{
std::cout << Foo{} << "\n";
}
You can use the standard library manipulator setw to set the width of a field, which often results in indenting the text. Here's how you use it:
cout << std::setw(10) << "Viola!" << std::endl;
This will print the word "Viola!" indented by 4 spaces. Why 4 spaces? The parameter to setw() determines the entire width of the "field", which includes the 6 characters in "Viola!".
By default, setw() will align the text to the right, but can be made to align left by using another manipulator left. Here's an example:
cout << std::setw(10) << std::left << "Viola!" << std::endl;
This will output the string "Viola!" with no indentation, but with 4 spaces after it.
That should answer your original question about a good way to indent, and setw() is not just a good way, but the standard way.
The second question asks about how to have persistent indentation, and the answer is that there is not an easy way. The easiest approach is to add the call to setw() (or whichever indentation method that you use) in each of the calls to cout.
In addition to those answers, you should consider replacing the use of "\n" in your calls to cout with a call to endl. endl is the "end of line" manipulator, and makes your code work properly with any output stream. The code would look like this:
auto& operator<<(std::ostream& os, Foo const& foo)
{
os << foo.i << std::endl;
os << foo.s << std::endl;
return os;
}

std::ostream printing address at end of function

I have the following function:
std::vector<double>residuals;
std::cout << Print_res(std::cout);
std::ostream& Print_res(std::ostream& os) const {
os << "\tresidual" << std::endl;
for (unsigned int i = 0 ; i < 22 ; i++) {
os << "\t\t" << residuals[i] << std::endl;
}
os << std::flush;
return os;
};
It prints the residuals correctly, but at the end of the output tags an address as follows:
2275
2279.08
2224.0835
0x80c5604
how do I fix this?
EDIT: after reading everyone's comments I replaced the call to the function Print_res with a std::copy as
std::copy(residuals.begin(), residuals.end(), std::ostream_iterator<double>(std::cout,"\n"));
and that did not print the address, so I presume there is something wrong in the way I have written the function.
std::cout << Print_res(std::cout);
This is not legal at global scope so the code that you have posted is not valid. If this statement were executed from, say, a function then Print_res would be called and then the return value of Print_res would also be streamed to std::cout. This is most likely not what you meant. You probably want just this:
Print_res(std::cout);
Your statement performs the equivalent of:
std::cout << std::cout;
In C++03 (which you must be using), std::cout has an operator void* (from std::basic_ios<char>) the result of which is what is being printed.

Convert double point coordinates into string

string Point::ToString(const Point& pt)
{
std::stringstream buffX; //"Incomplete type is not allowed"????
buffX << pt.GetX(); // no operator "<<" matches these operands????
std::stringstream buffY;
buffY << pt.GetY();
string temp = "Point(" + buffX + ", " + buffY + ")"; //???....how to combine a couple of strings into one?..
return temp.str();
}
I followed the code from similar questions, but the system says "Incomplete type is not allowed"---red line under buffX
also red line under "<<" says that---- no operator "<<" matches these operands
really don't know why..
Thank you!
You need to #include <sstream> to use std::ostringstream.
Then:
std::string Point::ToString(const Point& pt)
{
std::ostringstream temp;
temp << "Point(" << pt.GetX() << ", " << pt.GetY() << ")";
return temp.str();
}
It's not clear why you're passing in a Point, since this is a member of that class. Perhaps cleaner would be:
std::string Point::ToString() const
{
std::ostringstream temp;
temp << "Point(" << GetX() << ", " << GetY() << ")";
return temp.str();
}
This, perhaps incorrectly, assumes that GetX() and GetY() return some kind of numeric type (int, float, double, ...). If this is not the case, you may want to either change them (the principle of least astonishment) or access the underlying data members of the class directly.
If you're struggling with this kind of compiler error, I strongly recommend you get yourself a good C++ book.

Split array string in c++

I am new to cpp and have a situation in which I want to split array string
I have
for( i = k = 0; i < points[1].size(); i++ )
{
cout << points[1][k];
}
Output >>
[390.826, 69.2596]
[500.324, 92.9649]
[475.391, 132.093]
[5.60519e-44, 4.62428e-44]
I want
390.826
69.2596
500.324
92.9649
475.391
132.093
5.60519e-44
4.62428e-44
Please help me.Thanks
Assuming the type of point has public members x and y:
for( i = k = 0; i < points[1].size(); i++ )
{
cout << points[1][k].x << endl;
cout << points[1][k].y << endl;
}
If the members are something else, say, X and Y (the uppercase), then use the uppercase instead (or whatever it is).
The reason why you code prints the output that way, because operator<< has been overloaded for the type of the point. Something like:
std::ostream & operator<<(std::ostream & out, const point &p)
{
return out << "[" << p.x << "," << p.y << "]\n";
}
If you can search the above definition (or something similar) somewhere in your project source code, and then can change that to this:
std::ostream & operator<<(std::ostream & out, const point &p)
{
return out << p.x << "\n" << p.y << "\n";
}
then you wouldn't need to change the code in your for loop.
This has nothing to do with string splitting, what does points[1][k] actually return (i.e. it's type). Then look at how it has implemented the stream out operator (operator<<), and you'll see how the above is printed. This should give you a clue about the two individual values (i.e. fields of that *type), and you can simply access them and print them out.

Ostream << overloading confusion

When you're overloading the << operator for a class (pretend this is defined as a friend in SomeClass), why do you both take a reference to the ostream and return that ostream?
ostream& operator<<(ostream& s, const SomeClass& c) {
//whatever
return s;
}
What benefit can returning the ostream be when it was already directly modifiable by reference? This seems redundant to me - though I'm sure it's not :)
It allows to "chain" output together. As in :
std::cout << someObj << someValue;
This is equivalent to something like :
operator<<(operator<<(std::cout, someObj), someValue);
This is not redundant, but useful for chaining calls. It's easier to see with functions like std::string::append, so I'll start with that:
std::string mystring("first");
mystring.append(" second");
mystring.append(" third");
can be rewritten as:
std::string mystring("first").append(" second").append(" third");
This is possible because .append() returns a reference to the string it modified, so we can keep adding .append(...) to the end. The code correlating to what you are doing is changing from this:
std::cout << "first";
std::cout << " second";
std::cout << " third";
into this. Since operator<< returns the stream, we can also chain these!
std::cout << "first" << " second" << " third";
see the similarity, and usefulness?
So that you can write chained-invocation of operator<< as:
stream << s1 << s2 << s3 ;
If you don't return ostream&, then you cannot write it more than once.
You can think of that either as:
operator<<(operator<<(operator<<(stream, s1), s2), s3);
Or as,
((stream << s1) << s2) << s3 ;
First (stream << s1) returns stream& on which you again invoke << and it becomes stream << s2 which returns stream& on which you again invoke << and it becomes stream << s3.
Ah, this is so linked output, like
cout << "this " << "is " << "a pen" << endl;
will still work.