Boost logo

Boost :

From: Arturo_Cuebas_at_[hidden]
Date: 2004-08-17 12:41:56


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 syntactically prettier 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::* OneCharOverload)(char);
bind(static_cast<OneCharOverload>(C::F), &o, _1);

Here's my idea. If we had these:

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

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

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

template<typename TP1,
         typename TP2,
         typename TP3,
         typename TC,
         typename TR>
TR (TC::* resolve_cast3(TR (TC::* Func)(TP1, TP2, TP3)))
                                       (TP1, TP2, TP3)
{
    return Func;
}

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

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

If I want to specify C::F(char, int):

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

If the struct looked like this:

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

Things would be even nicer:

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

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

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

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

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

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

If I want to specify 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);

Is this worth the trouble?
Has anyone seen this before?
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.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk