Overload resolution & boost::bind

From: Arturo Cuebas (acuebas_at_NO_SPAM.houston.rr.com)
Date: 08/14/04


Date: Sat, 14 Aug 2004 05:11:14 GMT

The program below contains a compile error. Following the program you
will find the typical fix then my idea for a library that facilitates
a more elegant fix.

#include <boost\bind.hpp>

using namespace boost;

struct C
{
   void F(char, char){}
   void F(int, int){}
   void F(char, int){}
   void F(char){}
};

int main()
{
   C o;
   bind(
           C::F, // error: which C::F?
           &o,
          _1
          );
}

Typical solution:

bind(static_cast<void (C::*)(char)>(C::F), &o, _1);

And if you're a nice guy:

typedef void (C::* MemFun1Char)(char);
bind(static_cast<MemFun1Char>(C::F), &o, _1);

If we had these...:

template<typename TC, typename TR>
TR (TC::* resolve_cast0(TR (TC::* pFunc)(void)))(void)
{
   return pFunc;
}

template<typename TP, typename TC, typename TR>
TR (TC::* resolve_cast1(TR (TC::* pFunc)(TP)))(TP)
{
   return pFunc;
}

template<typename TP1, typename TP2, typename TC, typename TR>
TR (TC::* resolve_cast2(TR (TC::* pFunc)(TP1, TP2)))(TP1, TP2)
{
   return pFunc;
}

template<typename TP1,
               typename TP2,
               typename TP3,
               typename TC,
               typename TR>
TR (TC::* resolve_cast3(TR (TC::* pFunc)(TP1, TP2, TP3)))(TP1,

TP2,

TP3)
{
   return pFunc;
}

...etc; the bind call would look like this:

bind(resolve_cast1<char>(C::F), &o, _1);

Benefits:
1.) No ugly syntax due to specifying member function pointer type with
static_cast.
or
2.) One less line of code due to no typedef.

Another example; if I want to specify C::F(char, int):

bind(resolve_cast2<char, int>(C::F), &o, _1, _2);

Now, if we had this...:

struct D
{
   void F(char, char){}
   void F(char){}
};

...things would be even nicer:

If I want to call D::F(char, char):

bind(
        resolve_cast2(D::F), //notice no template params specified.
        &o,
         _1,
         _2);

If I want to call D::F(char):

bind(resolve_cast1(D::F), &o, _1);

It would be nice to do this, but I can't find a way:

If I want to call C::F(char):

bind(
        resolve_cast<char>(C::F), // notice no number appended
        &o,
        _1);

If I want to call D::F(char, char):

bind(
        resolve_cast<2>(D::F), // notice no number appended
        &o,
         _1);

Has anyone seen this before?
Do you think this is worth having in a library?
Is it possible to implement a form without a number appended?
Is there a name better than resolve_cast?

This was tested only in VC7.1.



Relevant Pages