In C++, neither
void ChkOverLoadCast(std::string&)
nor
void ChkOverLoadCast(bool &)
are suitable, because "x" is a temporary, and temporaries cannot be bound to non-const lvalue references.
MSVC, however, has a non-portable compiler extension which allows such binding. Given this extension, the overloads resolves unambiguously to the boolean overload.
You can obtain the same behavior from standard-conforming C++ compilers with the following test program:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
#include <iostream>
#include <string>
void FuncA(const std::string& str)
{
std::cout << "String";
}
void FuncA(const bool& b)
{
std::cout << "Bool";
}
int main()
{
FuncA("x");
}
|
Bool |
This is not a bug.
Here's what happens:
The function argument is "x", which is an array of 2 const char.
The only two functions you've provided (I'm assuming standards-conforming program) are a function taking
const bool&
and a function taking
const std::string&
.
The compiler builds conversion sequences:
1) const char[2] -> const char* -> void* -> bool -> const bool&
2) const char[2] -> const char* -> std::string -> const std::string&
it then evaluates which sequence is the better match. Sequence 1) is done entirely in implicit conversions. Sequence 2) includes a call to an object constructor. Sequence 1 is the better match.
Standard quotes
§13.3.3.2[over.ics.rank]/2
a standard conversion sequence is a better conversion sequence than a user-defined conversion sequence
|
§13.3.3.1.2[over.ics.user]/1
A user-defined conversion sequence consists of an initial standard conversion sequence followed by a user defined conversion followed by a second standard conversion sequence. If the user-defined conversion is specified by a constructor, the initial standard conversion sequence converts the source type to the type required by the argument of the constructor. |
PS: webJose's overload for const char* is indeed a better match than const bool&, because of §13.3.3.2/4 Two conversion sequences with the same rank are indistinguishable unless [...] A conversion that does not convert a pointer, a pointer to member, or std::nullptr_t to bool is better than one that does."