I've upgraded my code to VS C++.NET 2005 (Express) using /clr pure. My question is, why is there an exception to the rule in how pointer syntax is done in the event handlers? For example, why is this proper syntax: button->Click += gcnew EventHandler( this, &MyClass::MouseHandler ) ; The '&' seems like a hold over from the old syntax, except this is the NEW syntax (i.e., it never wanted the '&' before 2005 at all). Why was the '&' added (it's not like anything BUT a pointer would make sense), and why was the old syntax 'address of' symbol used? That is, before this was done like this: button->Click += new EventHandler( this, MyClass::MouseHandler ) ; That is, no '&'. Thus, it seems the proper transition would be to this syntax: button->Click += gcew EventHandler( this, MyClass::MouseHandler ) ; This means the only reason to add the '&' is if the line immediately above could somehow be ambiguous, which I don't think it can be. So adding the superfulous '&' seems odd. Further, almost humerously, the compile upon seeing the non-'&' form generates an error that basically says 'you need to add the '&'". Well, if it knows this, and there is no ambiguity involved, why not accept BOTH forms? Or dang it, why not provide the ability to click on such an error message and have an option for IT make the correction? And possibly allow a MAKE ALL CORRECTIONS button, letting the compiler do some of the work! Its really a bit irritating when it says 'this is what you did wrong, this is how its done' without the ability to fix it automatically (and such a method would not be prone to typos!)... [==P==]
On Mon, 28 Nov 2005 14:22:07 -0800, "Peter Oliphant" [quoted text, click to view] <poliphant@RoundTripInc.com> wrote: >I've upgraded my code to VS C++.NET 2005 (Express) using /clr pure. My >question is, why is there an exception to the rule in how pointer syntax is >done in the event handlers? > >For example, why is this proper syntax: > >button->Click += gcnew EventHandler( this, &MyClass::MouseHandler ) ; > >The '&' seems like a hold over from the old syntax, except this is the NEW >syntax (i.e., it never wanted the '&' before 2005 at all). Why was the '&' >added (it's not like anything BUT a pointer would make sense), and why was >the old syntax 'address of' symbol used? That is, before this was done like >this: > >button->Click += new EventHandler( this, MyClass::MouseHandler ) ; > >That is, no '&'. Thus, it seems the proper transition would be to this >syntax: > >button->Click += gcew EventHandler( this, MyClass::MouseHandler ) ; > >This means the only reason to add the '&' is if the line immediately above >could somehow be ambiguous, which I don't think it can be. So adding the >superfulous '&' seems odd. > >Further, almost humerously, the compile upon seeing the non-'&' form >generates an error that basically says 'you need to add the '&'". Well, if >it knows this, and there is no ambiguity involved, why not accept BOTH >forms? Or dang it, why not provide the ability to click on such an error >message and have an option for IT make the correction? And possibly allow a >MAKE ALL CORRECTIONS button, letting the compiler do some of the work! Its >really a bit irritating when it says 'this is what you did wrong, this is >how its done' without the ability to fix it automatically (and such a method >would not be prone to typos!)...
Earlier versions of VC++ accepted just about any syntax to mean pointer-to-member, which allowed people to make many subtle mistakes. For example, how is the compiler to know in general that A::F isn't simply the result of leaving off the parens on a function call? What about a->f? The C++ Standard says the only way to form a pointer-to-member is with the &A::F syntax, and that's a good thing. They've actually fixed a real problem with delegates; it used to be possible to create a C++ delegate from an unrelated object and pointer-to-member, but I just translated my old VC7.1 example to C++/CLI, and the compiler complains appropriately: TDelegate^ d = gcnew TDelegate(gcnew X, &Y::f); a.cpp(40) : error C3754: delegate constructor: member function 'Y::f' cannot be called on an instance of type 'X ^' In this program, X and Y are unrelated classes, but VC7.1 would allow the equivalent of the above to pass, causing errors at runtime instead of compile-time. -- Doug Harrison
Hi Doug, That brings up an interesting question. If it is illegal to create a handler with unrelated objects (which totally makes sense), why is it required to completely qualify the handler's name? That is, why do we have to do: Click += gcnew EventHandler( this, &MyClass::Handler ) ; why isn't this just fine: Click += gcnew EventHandler( this, &Handler ) ; [==P==] [quoted text, click to view] "Doug Harrison [MVP]" <dsh@mvps.org> wrote in message news:d41no1919gtekvl3rfeo6p8s1dh9p8djmm@4ax.com... > On Mon, 28 Nov 2005 14:22:07 -0800, "Peter Oliphant" > <poliphant@RoundTripInc.com> wrote: > >>I've upgraded my code to VS C++.NET 2005 (Express) using /clr pure. My >>question is, why is there an exception to the rule in how pointer syntax >>is >>done in the event handlers? >> >>For example, why is this proper syntax: >> >>button->Click += gcnew EventHandler( this, &MyClass::MouseHandler ) ; >> >>The '&' seems like a hold over from the old syntax, except this is the NEW >>syntax (i.e., it never wanted the '&' before 2005 at all). Why was the '&' >>added (it's not like anything BUT a pointer would make sense), and why was >>the old syntax 'address of' symbol used? That is, before this was done >>like >>this: >> >>button->Click += new EventHandler( this, MyClass::MouseHandler ) ; >> >>That is, no '&'. Thus, it seems the proper transition would be to this >>syntax: >> >>button->Click += gcew EventHandler( this, MyClass::MouseHandler ) ; >> >>This means the only reason to add the '&' is if the line immediately above >>could somehow be ambiguous, which I don't think it can be. So adding the >>superfulous '&' seems odd. >> >>Further, almost humerously, the compile upon seeing the non-'&' form >>generates an error that basically says 'you need to add the '&'". Well, if >>it knows this, and there is no ambiguity involved, why not accept BOTH >>forms? Or dang it, why not provide the ability to click on such an error >>message and have an option for IT make the correction? And possibly allow >>a >>MAKE ALL CORRECTIONS button, letting the compiler do some of the work! Its >>really a bit irritating when it says 'this is what you did wrong, this is >>how its done' without the ability to fix it automatically (and such a >>method >>would not be prone to typos!)... > > Earlier versions of VC++ accepted just about any syntax to mean > pointer-to-member, which allowed people to make many subtle mistakes. For > example, how is the compiler to know in general that A::F isn't simply the > result of leaving off the parens on a function call? What about a->f? The > C++ Standard says the only way to form a pointer-to-member is with the > &A::F syntax, and that's a good thing. > > They've actually fixed a real problem with delegates; it used to be > possible to create a C++ delegate from an unrelated object and > pointer-to-member, but I just translated my old VC7.1 example to C++/CLI, > and the compiler complains appropriately: > > TDelegate^ d = gcnew TDelegate(gcnew X, &Y::f); > > a.cpp(40) : error C3754: delegate constructor: member function 'Y::f' > cannot be called on an instance of type 'X ^' > > In this program, X and Y are unrelated classes, but VC7.1 would allow the > equivalent of the above to pass, causing errors at runtime instead of > compile-time. > > -- > Doug Harrison > Visual C++ MVP
[quoted text, click to view] "Peter Oliphant" <poliphant@RoundTripInc.com> wrote in message news:egECD3T9FHA.1248@TK2MSFTNGP14.phx.gbl... > Hi Doug, > > That brings up an interesting question. If it is illegal to create a > handler with unrelated objects (which totally makes sense), why is it > required to completely qualify the handler's name? That is, why do we have > to do: > > Click += gcnew EventHandler( this, &MyClass::Handler ) ; > > why isn't this just fine: > > Click += gcnew EventHandler( this, &Handler ) ;
Because the simple name 'Handler' is not in scope under normal C++ scoping rules. -cd
On Tue, 29 Nov 2005 15:36:42 -0800, "Peter Oliphant" [quoted text, click to view] <poliphant@RoundTripInc.com> wrote: >Hi Doug, > >That brings up an interesting question. If it is illegal to create a handler >with unrelated objects (which totally makes sense), why is it required to >completely qualify the handler's name? That is, why do we have to do: > >Click += gcnew EventHandler( this, &MyClass::Handler ) ; > >why isn't this just fine: > >Click += gcnew EventHandler( this, &Handler ) ;
It could do that, but it would make for a gratuitous incompatibility with Standard C++. Remember, in Standard C++, there's exactly one way to form a pointer to member. Also, qualifying the name with MyClass:: tells the compiler exactly where in the class hierarchy to start looking for the name "Handler". Normally, this would be the static type of *this, but it could also be a base class. You might argue that since there's an obvious choice of default starting point, the qualifier should be optional, but then we're back to the "gratuitous incompatibility". I do get the feeling you'd like the C# syntax better, which is, IIRC, something like EventHandler(this.Handler). -- Doug Harrison
Don't see what you're looking for? Try a search.
|