Search code examples
c++stringoverloadingdefault-parameters

c++ function overloading with bool and const char creates ambiguity without a warning (MSVC2012)


i have two functions for return value error handling:

static void handleError(int error, const std::string& message, bool bShowAll = false);

and

static void handleError(int error, const std::string& prefix, const std::string& message, bool bShowAll = false)

the call for this functions that i have the problem looks like this:

handleError(errro, "moduleA", "query failed");

now the problem pops up, that the invocation above leads into calling the first variant instead of the second one with a pass parameter of bShowAll resolved to "true". my best guess is that a "const char[]" is compatible with the "bool" type.

i have tried changing the order of the functions (by using a forward declaration for the second) but it did not help at all. what other options does c++ offer to solve that? (having type casts all around did not work - using some other type than bool, e.g. an enum-type with enum-symbol-equivalents for what bool is designed for went into nice operation. i think the default-value parameter init is the item that opened the door for this but MSVC 2012 itself did not hint for that ambiguity despite i am running it with warning level up to #4.)

note: i think stack-overflow is as well about learning how to do things nice, smart and also for learning from others: getting an own understanding on how things are designed in the area of computing and computer languages.


Solution

  • The problem is that "query failed" is of type const char[], it needs to be converted to std::string for handleError to be called. This is a user-defined conversion and has worse rank than the standard conversion (from const char[] to const char* and to bool).

    You can make it passing a std::string explicitly, to avoid the implicit user-defined conversion.

    handleError(errro, std::string("moduleA"), std::string("query failed"));
    

    Or since C++14

    using namespace std::string_literals;
    handleError(errro, "moduleA"s, "query failed"s);