Why can I pass a "C string" to a function expecting a std::string and it works?
I have a method:
void Foo::Bar(const std::string &str)
{
printf("%d", str.length());
}
and it works seamlessly when I do
foo.Bar("hello");
I thought "hello"
was a 开发者_如何学JAVAconst char *
, not a std::string
?
There are two ways user-defined types can be implicitly converted:
- With a conversion constructor (e.g. "std::string::string(const char* c_string)").
- With a conversion operator (e.g. "OldType::operator NewType() const").
Any constructor that takes a single parameter and does not use the keyword "explicit" defines an implicit conversion (from the type of the parameter, to the type of the object being constructed). The standard string class intentionally does not use "explicit" in order to provide the convenience of this conversion.
Because std::string has a constructor that takes a const char *
, C++ will automatically construct a temporary string object for you.
Technically it's a char const[6]
but yes you should be able to do this thanks to implicit conversion and one of std::string
constructors.
somewhat related to your question: if there is a time in C++ where you *explicit*ly don't want the compiler to change types for you like this, when a compatible constructor exists, you use the keyword "explicit" before the constructor. Then it will give you a compiler error. You can only do this with the types you create, however. Not with STL types like string.
Because there is an ?implicit? conversion from char *
to std::string
using the std::string(char *)
constructor.
Your string literal is a char const[6]
.
The name of it decays to const char*
for passing to the function.
Then an implicit conversion is performed, because:
- The function accepts a ref-to-const, meaning an
rvalue
can be bound to it - The
const char*
can be implicitly converted into anstd::string
rvalue
.
精彩评论