wrong cast passing string to overloaded func'

Hello to you all.
IDE:
Microsoft Visual studio 2008

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void ChkOverLoadCast(std::string& rStr)
{
    std::cout << "str";
}

void ChkOverLoadCast(bool &bChk)
{
	std::cout << "bool";
}

int _tmain(int argc, _TCHAR* argv[])
{
	ChkOverLoadCast("x");
}


The problem:
sending string "x" to an overloaded function ChkOverLoadCast calls to the unexpected function - ChkOverLoadCast(bool &bChk)
When I'm removing this function, The call is getting to ChkOverLoadCast(std::string& rStr) as expected.

The Questions:
1. Is it a bug in Microsoft compiler?
2. What happens there?

Thanks in advance

It seems to be compiler-dependent. For instance, GCC @ ideone.com doesn't even compile that function call. See http://ideone.com/lILbz .

Just move on and make your code clear: Either add a new overload for const char* or change the call in main() so you are explicit as to which overload to use.
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."
Last edited on
Topic archived. No new replies allowed.