my problem code:
#include <string>
#include <boost/function.hpp>
void func (const std::string&) {}
void func (const boost::function<void()>&) {}
int main() {
func (main); // good
func ("bad");
return 0;
}
=>
error: call of overloaded ‘func(const char [4])’ is ambiguous
overload.cpp:4: note: candidates are: void func(const std::string&)
overload.cpp:5: note: void func(const boost::function<void ()()>&)
I know I could resolve this by explicitly calling func (string ("bad")); or by providing a func (const char*), but I wonder if there is a way to keep the caller side as in the example and without introducing more overloads.
Maybe something with boost::enable_if? Thanks for any hints.
You can't easily solve this. boost::function<>
and std::function<>
don't support only functors callable by f()
, but also pointer to members callable by (secondArg.*firstArg)()
and data members, so their constructors basically slurp everything in, and later decide what to do with the type.
It's not trivial at all to write such a SFINAE testing class that guards from implicit conversions (and I'm not even sure whether it would be at all possible, since the Standard library doesn't do it. That must have some reason). Remember that a type may be callable because of many different properties - it may have a conversion function to function pointer type etc pp. Writing a SFINAE class that could make this work means to reject an implicit conversion in some cases and accept an implicit conversion in other cases based on really not obvious properties at all.
If you want to avoid this ambiguity, I would try just choose a different function name or if it's a one-shot problem, do the casting on the caller side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With