I was trying to clean up some code that uses char*
with std::string
and ran into a problem that is illustrated by the following code.
void Foo( int xIn , const std::string & fooIn )
{
std::cout << "string argument version called \n";
}
void Foo( int xIn , bool flagIn = true )
{
std::cout << "bool argument version called \n";
}
int main()
{
int x = 1;
Foo( x , "testing" );
return 0;
}
When I run the program I get bool argument version called. Is a char*
to bool
conversion preferred over char*
to const std::string&
or is Visual Studio 2008 playing tricks on me ?
Surprising as this behaviour is, the compiler is compliant: char*
to bool
conversion is preferred over the conversion to std::string
.
Read more here.
The exact rules are spelled out in the C++ standard. They're surprisingly complicated, but the following paragraph is crucial here:
C++11 13.3.3.2 Ranking implicit conversion sequences [over.ics.rank]
2 When comparing the basic forms of implicit conversion sequences (as defined in 13.3.3.1) — a standard conversion sequence (13.3.3.1.1) is a better conversion sequence than a user-defined conversion sequence or an ellipsis conversion sequence
char*
-to-bool
requires a "standard conversion sequence" whereas char*
-to-string
requires a "user-defined conversion sequence". Therefore, the former is preferred.
They are both a potential match, but the bool
version is preferred by the compiler because in order to match the string
version a user-provided (or, in this case, library-provided) conversion function is required.
If you really want to do this, providing an overload for const char*
can get you there:
void Foo( int xIn, const char* in)
{
return Foo( xIn, string(in) );
}
I would guess that by doing this, there's a very good chance that the compiler will perform quite a bit of optimization on it.
One simple fix would be to change the bool
to int
- there is an implicit conversion from a pointer to bool
, but not to int
. bool
to int
is not a problem, so the existing code that passes bools will continue to work.
Unfortunately this does impact the code readability a little by masking the parameter's intent.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With