String Literal Matches Bool Overload Instead of Std::String

String literal matches bool overload instead of std::string

"Hello World" is a string literal of type "array of 12 const char" which can be converted to a "pointer to const char" which can in turn be converted to a bool. That's precisely what is happening. The compiler prefers this to using std::string's conversion constructor.

A conversion sequence involving a conversion constructor is known as a user-defined conversion sequence. The conversion from "Hello World" to a bool is a standard conversion sequence. The standard states that a standard conversion sequence is always better than a user-defined conversion sequence (§13.3.3.2/2):

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

This "better conversion sequence" analysis is done for each argument of each viable function (and you only have one argument) and the better function is chosen by overload resolution.

If you want to make sure the std::string version is called, you need to give it an std::string:

Output::Print(std::string("Hello World"));

prevent string literals from being converted to bool versus std::string

what should I do to ensure this doesn't happen?

One possibility is to create an overload that accepts a char const* and make it a pass through to the overload that accepts a std::string.

void initialize(char const* name) { initialize(std::string(name)); }

Overloaded Bool/String Ambiguity

If you have C++11 you can use a delegating constructor:

A(char const* s) : A(std::string(s)) { }

The reason the boolean converting-constructor is chosen over the one for std::string is because the conversion from char const* to bool is a standard conversion while the one to std::string is a user-defined conversion. Standard conversions have a greater rank than user-defined conversions.

Want to assing std::string but compiler thinks is bool

A string literal like "Hola mundo" is a const char [], which decays to const char *.

The language standard defines an implicit conversion from any pointer to a bool.

The compiler chooses your bool operator as a better choice because calling your std::string operator would require the compiler to construct a temporary std::string object, while calling the bool operator does not.

To do what you want, add another operator for const char * so the compiler doesn't have to convert at all (it can optionally call the std::string operator if desired):

value_t operator=(const char* str) {
std::cout << "char*" << std::endl;
return *this;
};

value_t operator=(const char* str) {
return operator=(std::string(str));
};

Otherwise, you have to pass in a std::string explicitly:

val = std::string("Hola mundo");

On a side note, your operators should be returning a value_t& reference instead.



Related Topics



Leave a reply



Submit