Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ overload: string literal vs. boost::function ambiguity

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.

like image 344
denis Avatar asked Oct 13 '22 17:10

denis


1 Answers

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.

like image 178
Johannes Schaub - litb Avatar answered Nov 12 '22 22:11

Johannes Schaub - litb