From: daniel.kruegler@googlemail.com   
      
   Am 26.11.2012 23:17, schrieb Edmund Kapusniak:   
   > Is this valid C++?   
   >   
   > #include    
   >   
   > class base   
   > {   
   > };   
   >   
   > class derived : public base   
   > {   
   > public:   
   > virtual void method() { printf( "x()\n" ); }   
   > };   
   >   
   > void (base::*pmethod)() = static_cast< void (base::*)() >( &derived::method   
   );   
   >   
   > int main( int argc, char* argv[] )   
   > {   
   > derived d;   
   > base* b = &d;   
   > ( b->*pmethod )();   
   > return 0;   
   > }   
   >   
   > It appears to work, since b really does point to a derived. However I   
   > am concerned that it might be undefined behaviour, since I do not cast   
   > back to a void (derived::*)() before dereferencing to the   
   > pointer-to-member. Obviously if b pointed to a base (or an unrelated   
   > subclass of base) then this wouldn't work at all.   
   >   
   > I am hoping that it is legal. I think that it is useful to be able to   
   > dispatch calls to methods identified by their pointer-to-members without   
   > having to write a custom dispatch routine for each derived class.   
      
   The code looks ok to me. 5.2.9 p12 says:   
      
   "A prvalue of type “pointer to member of D of type cv1 T” can be   
   converted to a prvalue of type “pointer to member of B” of type cv2 T,   
   where B is a base class (Clause 10) of D, if a valid standard conversion   
   from “pointer to member of B of type T” to “pointer to member of D of   
   type T” exists (4.11), [..] If class B contains the original member, or   
   is a base or derived class of the class containing the original member,   
   the resulting pointer to member points to the original member. [ Note:   
   although class B need not contain the original member, the dynamic type   
   of the object with which indirection through the pointer to member is   
   performed must contain the original member; see 5.5. —end note ]"   
      
   It seems that the requirements are satisfied. I also notice that VS 2012   
   crashes with this code, but my current interpretation is that this must   
   be a compiler defect (I think it is due to non-conforming way in which   
   the VS compiler layouts pointer to members).   
      
   HTH & Greetings from Bremen,   
      
   Daniel Krügler   
      
      
   --   
    [ See http://www.gotw.ca/resources/clcm.htm for info about ]   
    [ comp.lang.c++.moderated. First time posters: Do this! ]   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|