Editted - please skip to the edit, which has the real problem
I frequently run into situations in my string helper library of stand-alone functions, where I provide overloads of a function with versions that take a char
and versions that take a std::string
.
The problem is, the overload then becomes ambiguous when passed a string literal (const char*
).
Example:
void myFunc(const std::string &subStr);
void myFunc(char character);
These two functions are implemented differently, one optimized for strings and one for a single char.
Howsoever, trying to call myFunc("literal")
results in ambiguity, despite me always wanting it to call the std::string
version.
This forces me to provide void myFunc(const char *str)
versions of my overloads, which only are stubs like:
void myFunc(const char *str)
{
myFunc(std::string(str));
}
Is there some way to make these stub functions unnecessary? I'd like to just be able to make void myFunc(char c)
'explicit', but you can't make non-constructor non-member functions explicit. Which would solve the problem instantly. =(...
(As an aside, why can't you make standalone functions explicit?)
Edit:
You know what they say about programmers coding too late into the night! (If you remember the joke, tell me, because I was too sleepy when I originally heard it and I've since forgotten it)
The real problem
I'm using MinGW v4.7.2, and the problem was alot different then my post originally assumed.
The problem is, I have several overloads. Yes, this example works fine:
void myFunc(const std::string &subStr);
void myFunc(char character);
But if you add an std::function overload, it breaks down:
void myFunc(const std::string &subStr);
//Not actually part of the problem; I was confused by part of the error message highlighting this function.
//void myFunc(char character);
void myFunc(std::function<bool(char)); //<-- The real problem
My string library has std::string, char, and std::function overloads (and occasionally a few more overloads for simplifying functions with alot of optional parameters).
When I have std::function as an overload, I get this error message:
error: call of overloaded ‘myFunc(const char [15])’ is ambiguous
candidates are:
void myFunc(char) <near match>
no known conversion for argument 1 from ‘const char [15]’ to ‘char’
void myFunc(std::function<bool(char)>)
void myFunc(const string&)
The myFunc(char) was how I initially got confused last night. Removing that overload from the code, I get the error message:
error: call of overloaded ‘myFunc(const char [15])’ is ambiguous
candidates are:
void myFunc(std::function<bool(char)>)
void myFunc(const string&)
How can I make a string literal choose the std::string over the std::function?
It's probably ambiguous because std::function's constructor is templated and is designed to take a function pointer, among other things.
Since my string library, specifically, uses only std::function<bool(char)>
and std::function<bool(const std::string&)>
, already typedef'd, I could inherit those into a class with an explicit constructor.
Is there other suggestions or options available?