Running the following MWE extracted from my pet project and compiled with GCC 4.9.1 (and 4.8.1 also)
#include <iostream>
#include <string>
#include <sstream>
class InputStringStream
{
public:
InputStringStream(const std::string& str) : istringstream(str), currentLine() {}
std::string readLine()
{
std::getline(istringstream, currentLine);
return currentLine;
}
private:
std::istringstream istringstream;
std::string currentLine;
};
int main()
{
std::string s = std::string("line1\nline2\nline3");
InputStringStream stream(s);
std::cout << stream.readLine() + "\n" + stream.readLine() + "\n" + stream.readLine() << std::endl;
return 0;
}
produces the following output
line3
line2
line1
while I expect
line1
line2
line3
What I'm doing wrong?
P.S. The same code compiled with Apple LLVM compiler version 5.1 produces what I expect. Visual C++ 2012 is on GCC side.
The & operator is recommended for string concatenation because it is defined exclusively for strings and reduces your chances of generating an unintended conversion.
C++ has a built-in method to concatenate strings. The strcat() method is used to concatenate strings in C++. The strcat() function takes char array as input and then concatenates the input values passed to the function.
The concatenation operator is a binary operator, whose syntax is shown in the general diagram for an SQL Expression. You can use the concatenation operator ( || ) to concatenate two expressions that evaluate to character data types or to numeric data types.
The order of evaluation of function arguments is unspecified, so what you're doing wrong is holding mistaken, unwarranted beliefs and expectations. (Overloaded operators like +
and <<
are just ordinary function calls.)
You have to extract the stream elements in a deterministic order, and it's your responsibility to do so. For example:
std::cout << stream.readLine() + '\n';
std::cout << stream.readLine() + '\n';
std::cout << stream.readLine() + '\n';
Even better, avoiding redundancy and temporary strings:
for (auto i : { 1, 2, 3 }) { std::cout << stream.readLine() << '\n'; }
The problem is not about associativity, in this expression:
stream.readLine() + "\n" + stream.readLine() + "\n" + stream.readLine()
It's unspecified which stream.readLine()
is called first.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With