Why don't C++03 file streams accept string constructor parameters?
-
13-11-2019 - |
Question
Why does the following code compile in C++11
and does not in C++03
? (both gcc
and cl
)
#include <string>
#include <iostream>
#include <fstream>
int main(int argc, char* argv[]) {
const std::string t("Hello");
std::ofstream out(t);
}
Why don't the C++03
streams accept std::string
as the constructor parameter? Was this decision based on something or did it happen accidentally?
Solution
The code fails when compiled with a strictly conforming C++03 compiler because the constructor that takes a std::string
was only added in C++11.
As to the question, "was it based on something smart", as the interface was added, it can be inferred that there was no technical reason for it to be omitted.
It's an addition of convenience as, if you have a std::string
, you can always call .c_str()
to get a C string suitable for use with the old interface. (As the documentation in C++11 says , the constructors that take std::string
have exactly the same effect as calling the corresponding constructor which takes a const char*
with the result of calling .c_str()
on the string.)
OTHER TIPS
As I recall, this was discussed on c.l.c++.m some years ago, and Andrew Koenig (I think it was Andrew, anyway) said it was actually brought up during some meetings, but the idea of accepting a string
was quickly conflated with the idea of accepting a wstring
as well, and from there turned into a discussion about support for internationalized character sets in file names, and ... shortly after that the whole idea was dropped because it had opened a big can of worms nobody was prepared to deal with right then.
They had simply forgotten about adding the string
constructor in C++03. Now that's fixed. This time round other things were forgotten, like make_unique
. There's always something more that one could have done. C++03 also forgot to specify default arguments for function templates, which are now included.
Edit: As @Charles says, it may not be a literal "forgetting", but rather, it's something that clearly should be there, but just hadn't been specified for some reason or another. Further examples are given by std::next
/std::prev
, which are a great relief, and std::to_string
and std::stoi/d/ul/ull
, which again make perfect sense, but nobody had gotten around to specifying them until this time round. There isn't necessarily a deep reason for their previous absence.