-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Igor R Sent: Saturday, September 18, 2010 8:57 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users] overload resolution with boost::function
I am trying to use objects of boost::function as parameters to overloaded function. However, the compiler fails to automatically resolve the function type when I use a function pointer:
a function pointer is implicitly convertible to boost::function, so there's an ambiguity. It seems that *any* function pointer is implicitly convertible to any boost::function object during overload resolution irrespective of the signatures of both the function and the function pointer. This seems to be different from using boost::function as variables inside a function and assigning a function pointer to it: #include <boost/function.hpp>
//void f(); void f(int); void accept( boost::function< void () > g); void accept( boost::function< void (int) > g); int main(int argc, char* argv[]) { typedef void (*fptr)(int); fptr F = f; boost::function< void () > F2 = f; return 0; } This issues an error when f is assigned to F2. The following code issues an overload resolution error, so there must an implicit conversion from void f(void) to boost::function< void() >: #include <boost/function.hpp> void f(int); void accept( boost::function< void () > g); void accept( boost::function< void (int) > g); int main(int argc, char* argv[]) { accept(f); return 0; } This seems not consistent for me and I can't figure out the cause.
Is there any way to have the accept function call resolved automatically without creating explicit boost::function object?
I don't know what you intend to do inside accept(), but maybe you could make it a template that expect a "callable" parameter.
The problem is that I want to do different things depending on the function type passed to accept. I am trying to create a factory for command objects. Unfortunately, these command objects have constructors with different signatures, so I need to register different factory methods for each command. Each factory is represented as a callable object returning a pointer to the command base. This works pretty well except that I have to specify the type of the boost::function object explicitly when I register the factory functions. class Base; class C1: public Base { }; class C2: public Base { public: explicit C2(int) {} }; class Factory { public: void registerFactory(int id, boost::function<Base ()> f) { nullaryContainer[id] = f; } void registerFactory(int id, boost::function<Base (int)> f) { unaryContainer[id] = f; } Base* create(int id) { return new nullaryContainer[id](); } Base* create(int id, int i) { return new unaryContainer[id](i); } private: std::map<int, boost::function<Base ()> > nullaryContainer; std::map<int, boost::function<Base (int> > unaryContainer; }; Base* createC2(int i); void register(Factory& f) { // ambigous call error f.registerFactory(createC2); }