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
Heterogeneous Containers in C++
How to Know the Exact Line of Code Where an Exception Has Been Caused
Representing 128-Bit Numbers in C++
Constexpr If and Static_Assert
High Resolution Timer With C++ and Linux
Which C I/O Library Should Be Used in C++ Code
Why Can't I Have a Non-Integral Static Const Member in a Class
What Is More Efficient? Using Pow to Square or Just Multiply It With Itself
Using Scanf() in C++ Programs Is Faster Than Using Cin
How to Get Error Message When Ifstream Open Fails
Why Is 'Std::Move' Named 'Std::Move'
How to Concatenate Two Strings in C++