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?

Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top