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. 4 2702
"Arturo Cuebas" <acuebas@NO_SPAM.houston.rr.com> wrote in message
news:8c********************************@4ax.com... 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);
[snipped solution involving templates]
While I admit that function pointer syntax can be ugly, the solution that
you proposed is unnecessary. IMHO, elegance is not measured in terms of
casts or punctuation symbols. While your proposed solution does eliminate
the function signature from the caller's code, it makes the caller's code
harder to follow. The proposed solution makes it harder to determine which
function is being called because the resolution is hidden by a template
function. Also, the solution does not eliminate the author's need to figure
out which function he/she needs to call, so it doesn't make anything easier
for him/her. In the end, the cure is worse than the disease.
--
David Hilsee
On Sat, 14 Aug 2004 01:31:19 -0400, "David Hilsee"
<da*************@yahoo.com> wrote: "Arturo Cuebas" <acuebas@NO_SPAM.houston.rr.com> wrote in message news:8c********************************@4ax.com.. . 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);[snipped solution involving templates]
While I admit that function pointer syntax can be ugly, the solution that you proposed is unnecessary. IMHO, elegance is not measured in terms of casts or punctuation symbols.
I misused the word "elegant". Maybe "syntactically prettier" would
have been more appropriate.
While your proposed solution does eliminate the function signature from the caller's code, it makes the caller's code harder to follow. The proposed solution makes it harder to determine which function is being called because the resolution is hidden by a template function.
You have to explicitly specify the parameter types of the function you
want the template to resolve the overload to. This explicit
specification of the parameter types puts which function you want
called right in your face.
Consider:
resolve_cast1<char>(C::F)
- The number indicates how many parameters the function you want
called takes (incidentally, I don't like this, I wish I could have
done resolve_cast<1, char>(C::F) or even resolve_cast<char>(C::F), but
I couldn't figure it out).
- The template parameter(s) indicate what the parameter types are of
the function you want to call.
These two aspects make it clear as day which function you want to
call: The overload of F that takes 1 parameter of type char.
Now, consider:
static_cast<void (C::*)(char)>(C::F)
Read from left to right (disregarding the parens and angle brackets):
"void" - The return type of the overloaded function - just because
it's part of the type you're casting to it has to be specified.
"C" - The class the function belongs to. Again, just because it's part
of the type you're casting to it has to be specified. Also, this is
redundant, as it is already specified in the "parameter" to
static_cast.
"::*" - Would you mind if all I said about this is "ugh"?
char - Now we've finally got to the part that truly differentiates the
function we want from the rest of the functions.
The parameter types are the only differences between functions that
allow the functions to be overloaded therefore it makes a certain
sense that that is the only thing the coder should have to specify -
and with this facility, that's all the coder has to.
Also, the solution does not eliminate the author's need to figure out which function he/she needs to call,
psycic_resolve_cast<>?
so it doesn't make anything easier for him/her.
I think it's easier to follow this:
resolve_cast1<char>(C::F)
than this:
static_cast<void (C::*)(char)>(C::F)
but that's just me. Maybe it just takes a little familiarity with what
resolve_cast1<> does, just like it takes a little familiarity with
lexical_cast<> and numeric_cast<> to know what they do.
In the end, the cure is worse than the disease.
"Arturo Cuebas" <acuebas@NO_SPAM.houston.rr.com> wrote in message
news:1r********************************@4ax.com...
<snip> I think it's easier to follow this:
resolve_cast1<char>(C::F)
than this:
static_cast<void (C::*)(char)>(C::F)
but that's just me. Maybe it just takes a little familiarity with what resolve_cast1<> does, just like it takes a little familiarity with lexical_cast<> and numeric_cast<> to know what they do.
By the way, I believe you're missing the ampersands in your code (&C::F).
Keep in mind that it doesn't "do" anything. The other two actually provide
some functionality (conversion and range checking). The resolve_cast1
function template just provides an alternate syntax for specifying which
overload should be used. If you like it, that's fine, but I'm not
impressed. Function pointer syntax doesn't disgust me to the point where I
feel like it must be hidden behind template code, and the tiny bit of
redundancy doesn't bother me, either. Don't take it personally. I
generally object to additional code that is merely for aesthetics and has
little to no technical benefit.
--
David Hilsee
Arturo,
You might want to repost this on the boost mailing lists. You may get some
insights from the authors.
Jeff F
"Arturo Cuebas" <acuebas@NO_SPAM.houston.rr.com> wrote in message
news:8c********************************@4ax.com... 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. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: P G |
last post by:
I hope this is on topic here. I have a problem compiling a simple
example of the use of boost::bind. Please take a look at the program
below.
...
|
by: Russell Hind |
last post by:
Is it possible to create a boost::bind object for a managed class
method? With non-managed classes, I can do
boost::function<void ()> f = boost::bind(&Class_c::Function, this);
Is there a way...
|
by: IndyStef |
last post by:
I am trying to use boost's bind on a member function, on the VC8
compiler.
After using several different attempts, I could not get it to work.
Does
anybody know what is wrong with the code below?...
|
by: yinglcs |
last post by:
I have a function in STL which add the 'area'
attribute of a list of Rect.
template< class T1, class T2> class add_area_per_cent
: public binary_function<T2, T1, T2>
{
public:...
|
by: Olaf Petzold |
last post by:
Hi,
at this time I try to combine Qt and boost. Unfortunately I've run into
trouble:
void QWidget::insertAction ( QAction * before, QAction * action );
class QAction : public QWidget { ... };...
|
by: Tigera |
last post by:
Greetings,
I am trying to learn to use the Boost library, and I've run into a
frustrating problem with the line marked here:
#include <boost/function.hpp>
#include <boost/functional.hpp>...
|
by: =?iso-8859-1?B?Tm9yZGz2dw==?= |
last post by:
Hey there, C++ Coders!
I am learning multi-threading with boost and have come up with the
following code example shown below.
This example implements a test of the producer-consumer design...
|
by: joe |
last post by:
I expected I could construct code like the following:
return *(std::min_element(vec.begin(), vec.end(),
bind(less<double>(),
bind(&entry::foo, _1),
bind(&entry::foo, _2))));
But if vec is...
|
by: kittymaguire |
last post by:
I am using VC2005 and have refined new to be new
(_NORMAL_BLOCK ,__FILE__, __LINE__) for the debug build so that the
location of memory leaks are reported.
The problem that I have is when, I...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
|
by: conductexam |
last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
| |