A
Arturo Cuebas
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.
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.