Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
So, why, when I have defined that the method can accept boolean and string, does it use the boolean overload when I pass in a non-boolean value?
EDIT: I come from a C#/Java environment, so quite new to C++!
–
–
–
–
"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"));
–
–
–
–
–
Not sure why nobody posted this, but you can add another overload that converts from const char* to std::string for you. This saves the caller from having to worry about this.
class Output
public:
static void Print(bool value)
std::cout << value ? "True" : "False";
static void Print(std::string value)
std::cout << value;
// Just add the override that cast to std::string
static void Print(const char* value)
Output::Print(std::string(value));
FWIW, it can be addressed this way (if templates can be used), if you don't want to add overloads for const char*
.
#include <iostream>
#include <string>
#include <type_traits>
template <typename Bool,
typename T = std::enable_if_t<std::is_same<Bool, bool>{}>>
void foo(Bool)
std::cerr << "bool\n";
void foo(const std::string&)
std::cerr << "string\n";
int main()
foo("bar");
foo(false);
Since C++14 we have the operator""s
from the std::string_literals
namespace, which can be used to tell the compiler to bind to the string
(or string_view
in C++17) overload:
using namespace std::string_literals;
Output::Print("Hello World"s);
Prints: Hello World
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.