Boost logo

Boost Users :

Subject: Re: [Boost-users] overload resolution with boost::function
From: Jens Auer (jensa_at_[hidden])
Date: 2010-09-20 03:38:41


> -----Original Message-----
> From: boost-users-bounces_at_[hidden]
> [mailto:boost-users-bounces_at_[hidden]] On Behalf Of Igor R
> Sent: Saturday, September 18, 2010 8:57 PM
> To: boost-users_at_[hidden]
> 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);
}


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net