Why don't the std::fstream classes take a std::string?

c++, file-io, stdstring, stl

Solution

By taking a C string the C++03 `std::fstream` class reduced dependency on the `std::string` class. In C++11, however, the `std::fstream` class does allow passing a `std::string` for its constructor parameter.

Now, you may wonder why isn't there a transparent conversion from a `std:string` to a C string, so a class that expects a C string could still take a `std::string` just like a class that expects a `std::string` can take a C string.

The reason is that this would cause a conversion cycle, which in turn may lead to problems. For example, suppose `std::string` would be convertible to a C string so that you could use `std::string`s with `fstream`s. Suppose also that C string are convertible to `std::string`s as is the state in the current standard. Now, consider the following:

void f(std::string str1, std::string str2);
void f(char* cstr1, char* cstr2);

void g()
{
    char* cstr = "abc";
    std::string str = "def";
    f(cstr, str);  // ERROR:  ambiguous
}

Because you can convert either way between a `std::string` and a C string the call to `f()` could resolve to either of the two `f()` alternatives, and is thus ambiguous. The solution is to break the conversion cycle by making one conversion direction explicit, which is what the STL chose to do with `c_str()`.

Problem

This isn't a design question, really, though it may seem like it. (Well, okay, it's kind of a design question). What I'm wondering is why the C++ `std::fstream` classes don't take a `std::string` in their constructor or open methods. Everyone loves code examples so: ``` #include <iostream> #include <fstream> #include <string> int main() { std::string filename = "testfile"; std::ifstream fin; fin.open(filename.c_str()); // Works just fine. fin.close(); //fin.open(filename); // Error: no such method. //fin.close(); } ``` This gets me all the time when working with files. Surely the C++ library would use `std::string` wherever possible?

Original source