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_cas t<void (C::*)(char)>(C ::F), &o, _1);
And if you're a nice guy:
typedef void (C::* MemFun1Char)(ch ar);
bind(static_cas t<MemFun1Char>( C::F), &o, _1);
If we had these...:
template<typena me TC, typename TR>
TR (TC::* resolve_cast0(T R (TC::* pFunc)(void)))( void)
{
return pFunc;
}
template<typena me TP, typename TC, typename TR>
TR (TC::* resolve_cast1(T R (TC::* pFunc)(TP)))(TP )
{
return pFunc;
}
template<typena me TP1, typename TP2, typename TC, typename TR>
TR (TC::* resolve_cast2(T R (TC::* pFunc)(TP1, TP2)))(TP1, TP2)
{
return pFunc;
}
template<typena me TP1,
typename TP2,
typename TP3,
typename TC,
typename TR>
TR (TC::* resolve_cast3(T R (TC::* pFunc)(TP1, TP2, TP3)))(TP1,
TP2,
TP3)
{
return pFunc;
}
....etc; the bind call would look like this:
bind(resolve_ca st1<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_ca st2<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_ca st1(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<ch ar>(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 2717
"Arturo Cuebas" <acuebas@NO_SPA M.houston.rr.co m> wrote in message
news:8c******** *************** *********@4ax.c om... 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_cas t<void (C::*)(char)>(C ::F), &o, _1);
And if you're a nice guy:
typedef void (C::* MemFun1Char)(ch ar); bind(static_cas t<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_SPA M.houston.rr.co m> 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_cas t<void (C::*)(char)>(C ::F), &o, _1);
And if you're a nice guy:
typedef void (C::* MemFun1Char)(ch ar); bind(static_cas t<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 "syntactica lly 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<c har>(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<ch ar>(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<voi d (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<c har>(C::F)
than this:
static_cast<voi d (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_SPA M.houston.rr.co m> wrote in message
news:1r******** *************** *********@4ax.c om...
<snip> I think it's easier to follow this:
resolve_cast1<c har>(C::F)
than this:
static_cast<voi d (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_SPA M.houston.rr.co m> wrote in message
news:8c******** *************** *********@4ax.c om... 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_cas t<void (C::*)(char)>(C ::F), &o, _1);
And if you're a nice guy:
typedef void (C::* MemFun1Char)(ch ar); bind(static_cas t<MemFun1Char>( C::F), &o, _1);
If we had these...:
template<typena me TC, typename TR> TR (TC::* resolve_cast0(T R (TC::* pFunc)(void)))( void) { return pFunc; }
template<typena me TP, typename TC, typename TR> TR (TC::* resolve_cast1(T R (TC::* pFunc)(TP)))(TP ) { return pFunc; }
template<typena me TP1, typename TP2, typename TC, typename TR> TR (TC::* resolve_cast2(T R (TC::* pFunc)(TP1, TP2)))(TP1, TP2) { return pFunc; }
template<typena me TP1, typename TP2, typename TP3, typename TC, typename TR> TR (TC::* resolve_cast3(T R (TC::* pFunc)(TP1, TP2, TP3)))(TP1,
TP2,
TP3) { return pFunc; }
...etc; the bind call would look like this:
bind(resolve_ca st1<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_ca st2<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_ca st1(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<ch ar>(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.
/**************************************************************************/
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
|
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 to do this for __gc classes? I do want to be able to
assign the result to a boost::function, but can write my own wrapper if
necessary.
Thanks
|
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? The function that
doesn't
compile is foo::DoTheStuff. All three variations of the for-each loop
won't
build.
|
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:
add_area_per_cent() { }
|
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 { ... };
class ActionCategory {
...
| |
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>
#include <boost/bind.hpp>
#include <iostream>
|
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
pattern.
gcc-4.1.2 however complains with errors about my use of boost::bind().
Doesn't bind support this way of specifying a function and its...
|
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 only size 1, this returns '0'. min_element should work
on size one vectors.
If I add the guard "if(vec.size() == 1) { return *(vec.begin()); } "
|
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 try to bind a functor using
boost::bind
boost::bind(&BoostWorkerThread::Stop, this)
I get an syntax error in function_template.hpp '('
|
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
|
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it.
First, let's disable language...
| |
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it. ...
|
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
|
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes...
|
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 then checking html paragraph one by one.
At the time of converting from word file to html my equations which are in the word document file was convert...
|
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
| |
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...
| |