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()
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…