Im working with the book SFML Game Development by Examples and I dont really get what this sentence does. I've never seen something like this
void Anim_Directional::ReadIn(std::stringstream& l_stream){
l_stream >> m_frameStart >> m_frameEnd >> m_frameRow
>> m_frameTime >> m_frameActionStart >> m_frameActionEnd;
}
In C++ they got the "bright" idea of overloading the rightshift and leftshift operators with streams to represent serialization/deserialization.
stream >> var
means "read var from stream".
Symmetrically
stream << var
mean "put var into stream"
The operation of "streaming" in or out also returns the stream, so you can chain operations like:
stream >> var1 >> var2;
Note that the "streaming" was chosen just because of the look and because the priority was considered reasonable, but it's still just an overloaded operator and implies for example no strict sequence of evaluation. For example in:
stream << f() << g();
may be function g is called (somewhat surprisingly) before function f.
NOTE: the sequencing problem was handled by hammering this special case in last C++ standard (C++17). While it doesn't hold in general it's guaranteed for shift operators (presumably for this specific reason). So in f()+g() may be f is called later than g, but in f()<<g() this cannot happen.
C++ allows you to overload >> and << operators. std::stringstream is a derivative of std::istream and it inherits the >> operator overloads of std::istream.
The std::istream has a bunch of overloads for many common types. You can find a list of them here.
A typical std::istream >> operator overload looks as follows:
std::istream& operator>>(std::istream& stream, YourType& var) {
/*
** code here to parse and read a 'YourType' into 'var'
*/
/* var is set */
return stream; /* return the same stream to allow chaining */
}
When you do some_stream >> YourType_object, the matching >> operator overload is invoked. In the aforementioned case, our operator overload is invoked with stream parameter taking some_stream and var taking YourType_object.
The >> overloads (and << overloads too) intelligently return the stream which they operated; thereby, allowing a series of >> operators to be chained.
Related
I have looked to no avail, and I'm afraid that it might be such a simple question that nobody dares ask it.
Can one input multiple things from standard input in one line? I mean this:
float a, b;
char c;
// It is safe to assume a, b, c will be in float, float, char form?
cin >> a >> b >> c;
Yes, you can input multiple items from cin, using exactly the syntax you describe. The result is essentially identical to:
cin >> a;
cin >> b;
cin >> c;
This is due to a technique called "operator chaining".
Each call to operator>>(istream&, T) (where T is some arbitrary type) returns a reference to its first argument. So cin >> a returns cin, which can be used as (cin>>a)>>b and so forth.
Note that each call to operator>>(istream&, T) first consumes all whitespace characters, then as many characters as is required to satisfy the input operation, up to (but not including) the first next whitespace character, invalid character, or EOF.
Yes, you can.
From cplusplus.com:
Because these functions are operator overloading functions, the usual way in which they are called is:
strm >> variable;
Where strm is the identifier of a istream object and variable is an object of any type supported as right parameter. It is also possible to call a succession of extraction operations as:
strm >> variable1 >> variable2 >> variable3; //...
which is the same as performing successive extractions from the same object strm.
Just replace strm with cin.
Both >> and + operators are binary operators. What does the difference in their syntaxes mean?
Why does >> have a return type (return by reference)? I know it is stupid but I am really confused between their syntaxes and would love a brief explanation.
Sparse operator +(Sparse &s); //code for plus operator
friend istream & operator >>(istream &is,Sparse &s); //code for insertion operator
operator+ combines the data of two input objects (in your example, the left-hand object is *this) and returns a new object containing the combined data.
operator>> (and operator<<) returns a reference to the stream that is being acted on. This allows for chaining multiple stream operations, eg:
cin >> var1 >> var2 ...;
// which is the same as:
// cin.operator>>(var1).operator>>(var2) ...
// or:
// operator>>(operator>>(cin, var1), var2) ...
// etc, depending on the particular types and operator overloads being used
cout << var1 << var2 ...;
// which is the same as:
// cout.operator<<(var1).operator<<(var2) ...
// or:
// operator<<(operator<<(cout, var1), var2) ...
// etc, depending on the particular types and operator overloads being used
Without being able to chain, stream operations would have to be called individually instead, eg:
cin >> var1;
cin >> var2;
...
cout << var1;
cout << var2;
...
I'm having a trouble when I use while(cin) with struct. Would someone please make me clear about this problem? I don't know whether this kind of post was asked or not. If it was please forgive me and my bad english as well.
struct ThiSinh{
string m_HT;
float m_H;
};
I overload operator >> for it
bool operator >> (istream& is, ThiSinh &ts){
getline(is, ts.m_HT);
is >> ts.m_H;
is.ignore();
return ???;
}
Because while (cin >> ThiSinh) require a bool type, so I dont know what number or data it should return. And how to break the while loop when I press ctrl + Z.
I have also tried
while(cin){
ThiSinh ts;
cin >> ts;
}
and it worked but I dont want to get that false data. So someone please helps me out. Thanks in advance.
Your operator >> returns a bool, which is extremely unusual for a stream extraction operator, and renders it unusuable in most streaming contexts. Such operators are expected to return a reference to the stream on which they operate:
istream& operator >> (istream& is, ThiSinh &ts){
getline(is, ts.m_HT);
is >> ts.m_H;
is.ignore();
return is;
}
This is how multiple exrtactions actually work:
std::cin >> a >> b >> c;
Effectively, this first does auto &tmp = operator>>(std::cin, a), and then calls operator>>(tmp, b), and so on.
The reason why streams (and by extension, stream extraction operations) can be used in conditionals is that std::istream (and std::ostream) defines a conversion to bool (which returns true iff the stream is in error-free state); that conversion is then invoked by the conditional.
In other words, this:
while (std::cin >> ts)
effectively becomes this:
while (static_cast<bool>(operator>>(std::cin, ts)))
and the cast is possible because operator>> returns std::istream& and std::istream defines a conversion to bool.
I've used statements such as this quite a bit in my C++ programming:
std::string s;
std::ifstream in("my_input.txt");
if(!in) {
std::cerr << "File not opened" << std::endl;
exit(1);
}
while(in >> s) {
// Do something with s
}
What I want to know is, why does this work?
I looked at the return value of operator>>, and it's an istream object, not a boolean. How does an istream object somehow get interpreted as a bool value that can be put inside of if statements and while loops?
The base class std::basic_ios provides an operator bool() method that returns a boolean representing the validity of the stream. For example, if a read reached the end of file without grabbing any characters, then std::ios_base::failbit will be set in the stream. Then operator bool() will be invoked, returning !fail(), at which time extraction will stop because the condition is false.
A conditional expression represents an explicit boolean conversion, so this:
while (in >> s)
is equivalent to this
while (static_cast<bool>(in >> s))
which is equivalent to this
while ((in >> s).operator bool())
which is equivalent to
while (!(in >> s).fail())
std::basic_ios, from which the input and output streams inherit, has the conversion function operator bool (or operator void* prior to C++11 to get around the safe-bool problem, which is no longer an issue thanks to the explicit keyword).
See std::basic_ios::operator bool:
This operator makes it possible to use streams and functions that return references to streams as loop conditions, resulting in the idiomatic C++ input loops such as while(stream >> value) {...} or while(getline(stream, string)){...}. Such loops execute the loop's body only if the input operation succeeded.
I have looked to no avail, and I'm afraid that it might be such a simple question that nobody dares ask it.
Can one input multiple things from standard input in one line? I mean this:
float a, b;
char c;
// It is safe to assume a, b, c will be in float, float, char form?
cin >> a >> b >> c;
Yes, you can input multiple items from cin, using exactly the syntax you describe. The result is essentially identical to:
cin >> a;
cin >> b;
cin >> c;
This is due to a technique called "operator chaining".
Each call to operator>>(istream&, T) (where T is some arbitrary type) returns a reference to its first argument. So cin >> a returns cin, which can be used as (cin>>a)>>b and so forth.
Note that each call to operator>>(istream&, T) first consumes all whitespace characters, then as many characters as is required to satisfy the input operation, up to (but not including) the first next whitespace character, invalid character, or EOF.
Yes, you can.
From cplusplus.com:
Because these functions are operator overloading functions, the usual way in which they are called is:
strm >> variable;
Where strm is the identifier of a istream object and variable is an object of any type supported as right parameter. It is also possible to call a succession of extraction operations as:
strm >> variable1 >> variable2 >> variable3; //...
which is the same as performing successive extractions from the same object strm.
Just replace strm with cin.