问题
I have the following code:
#include <iostream>
#include <string>
void foo(bool a)
{
std::cout << "bool" << std::endl;
}
void foo(long long int a)
{
std::cout << "long long int" << std::endl;
}
void foo(const std::string& a)
{
std::cout << "string" << std::endl;
}
int main(int argc, char* args[])
{
foo("1");
return 0;
}
When executing I get this output:
bool
I would have expected as output:
string
Why does g++ 4.9 implicitly cast this string to bool?
回答1:
Your compiler is interpreting the standard correctly. Yes, this is a tricky corner case that many interviewers ask so they appear smarter than they really are.
The route const char[2]
(the formal type of the literal "1"
) to const char*
to bool
is a standard conversion sequence, since it uses exclusively built-in types.
Your compiler must favour that to a user-defined conversion sequence, viz. the std::string
constructor from a const char*
.
The presence of the overload void foo(long long int a)
is a red herring.
You can rather elegantly work around this in C++11 by dropping your overload to bool
, and writing
#include <type_traits>
template <
typename Y,
typename T = std::enable_if_t<std::is_same<Y, bool>{}>
>
void foo(Y)
{
std::cout << "bool" << std::endl;
}
in its place. The compiler will then favour the std::string
for const char[N]
over the template (as that is one of the requirements of overload resolution). Nice!
回答2:
"1"
is a string literal, which - when used as function argument - decays to a pointer of type const char*
. As there is no overload for function foo
taking a const char*
, but there is a standard conversion from const char*
to bool
, it falls back to foo(bool)
. Note that a pointer value, when taken as a bool argument, is interpreted like somePtr==nullptr ? false : true
.
回答3:
"1" is a string literal, that is array of char
that gets converted to pointer and then to bool
. Notice that this path is preferred to implicit construction of a temporary std::string
object.
来源:https://stackoverflow.com/questions/44021989/implicit-cast-from-const-string-to-bool