The canonical way to read lines from a text file is:
std::fstream fs("/tmp/myfile.txt");
std::string line;
while (std::getline(line, fs)) {
doThingsWith(line);
}
(no, it is not while (!fs.eof()) { getline(line, fs); doThingsWith(line); }!)
This works beacuse std::getline returns the stream argument by reference, and because:
- in C++03, streams convert to
void*, via anoperator void*() constinstd::basic_ios, evaluating to the null pointer value when thefailerror flag is set;- see
[C++03: 27.4.4]&[C++03: 27.4.4.3/1]
- see
- in C++11, streams convert to
bool, via anexplicit operator bool() constinstd::basic_ios, evaluating tofalsewhen thefailerror flag is set- see
[C++11: 27.5.5.1]&[C++11: 27.5.5.4/1]
- see
In C++03 this mechanism means the following is possible:
std::cout << std::cout;
It correctly results in some arbitrary pointer value being output to the standard out stream.
However, despite operator void*() const having been removed in C++11, this also compiles and runs for me in GCC 4.7.0 in C++11 mode.
How is this still possible in C++11? Is there some other mechanism at work that I’m unaware of? Or is it simply an implementation “oddity”?
I’m reasonably certain this is not allowed/can’t happen in a conforming implementation of C++11.
The problem, of course, is that right now, most implementations are working on conforming, but aren’t there completely yet. At a guess, for many vendors, this particular update is a fairly low priority. It improves error checking, but does little (or nothing) to enable new techniques, add new features, improve run-time efficiency, etc. This lets the compiler catch the error you’ve cited (
some_stream << some_other_stream) but doesn’t really make a whole lot of difference otherwise.If I were in charge of updating a standard library for C++11, I think this would be a fairly low priority. There are other changes that are probably as easy (if not easier) to incorporate, and likely to make a much bigger difference to most programmers.
To use one of the examples you gave, if I were in charge of updating the VC++ standard library to take advantage of the compiler features added in the November CTP, my top priority would probably be to add constructors to the standard container types to accept
initialization_lists. These are fairly easy to add (I’d guess one person could probably add and test them in under a week) and make quite an obvious, visible difference in what a programmer can do.