Topic: static call of virtual member funtion using pointer to member function


Author: AllanW@my-dejanews.com
Date: 1998/12/02
Raw View
In article <newscache$jrga3f$sif@smaug.impaq.com.pl>,
  "RafalD" <rdzbek@impaq.com.pl> wrote:

> I'm surprised that C++ does not provide some notion for choosing static
> semantic (against virtual) for a pointer to a virtual member function.
> Does anybody know if there are any semantic problems behind that decision or
> it is only to make the C++ compiler implementers life easier?

Neither one. I'm sure that some of the compiler writers will tell
you that the only time the standard went out of it's way to make
life easier for them is when the problem would otherwise have been
literally impossible.

The reason that C++ doesn't have what you want is that virtual
keywords were invented for a specific purpose. The designers of
C++ had to go out of their way to ensure that pointers to member
functions didn't violate that purpose. They succeeded.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "RafalD" <rdzbek@impaq.com.pl>
Date: 1998/12/01
Raw View
>> struct A
>>   {
>>   virtual void f() {std::cout << "\nA::f"; }


        void non_virtual_f() { A::f(); }

>>   };
>> struct B: A
>>   {
>>   virtual void f() {std::cout << "\nB::f"; }
>>   };
>>
>> int main()
>>   {
>>   A a;
>>   memb_fun_clbk<A, &A::f>(&a);  //prints: A::f
>>
>>   B b;
>>   memb_fun_clbk<A, &A::f>(&b);
>>     //prints: B::f
>>     //would like to have: A::f

        memb_fun_clbk<A, &A::non_virtual_f>(&b); // now displays A::f

>>   return 0;
>>   }


Thanks, that could be a solution. But unfortunately that forces the user to
define another member function in the class A which can come from a third
party library (modifications in that case are not allowed). There is one
workaround for that case.
Anyway all these solutions are invasive.
I'm trying to provide a generic solution, not forcing the user to define
additional functions or member functions.
I'm surprised that C++ does not provide some notion for choosing static
semantic (against virtual) for a pointer to a virtual member function.
Does anybody know if there are any semantic problems behind that decision or
it is only to make the C++ compiler implementers life easier?





[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: AllanW@my-dejanews.com
Date: 1998/12/01
Raw View
In article <newscache$zcg83f$1z8@smaug.impaq.com.pl>,
  RafalD <rdzbek@impaq.com.pl> wrote:

> The following program prints:
>     A::f
>     B::f.
> I tried to force EGCS compiler to print
>     A::f
>     A::f
> by changing the body of the function template from:
>     (pObj->*MF)()
> to:
>     (pObj->*Class::MF)()
> but the compiler failed:
>     t.cpp: In function `void memb_fun_clbk<A, A::f()>(struct A *)':
>     t.cpp:21:   instantiated from here
>     t.cpp:6: `MF' is not a member of type `A'
>
> MF is compile time constant (non-type template argument).
> Is that deficiency of EGCS compiler or is the syntax incorrect?
> Is there any other way to get expected behavior?
>
>     Thanks,
>         Rafal Dzbek (rdzbek@impaq.com.pl)
>
> ////////////////////////////////////////////////////////////////////////////
> //////
>
> #include <iostream>
>
> template < typename Class, void (Class::*MF)() >
> void memb_fun_clbk( Class* pObj )
>   {
>     return (pObj->*MF)();
>   }
>
> struct A
>   {
>   virtual void f() {std::cout << "\nA::f"; }
>   };
> struct B: A
>   {
>   virtual void f() {std::cout << "\nB::f"; }

    void non_virtual_f() { B::f(); } // Try this instead

>   };
>
> int main()
>   {
>   A a;
>   memb_fun_clbk<A, &A::f>(&a);  //prints: A::f
>
>   B b;
>   memb_fun_clbk<A, &A::f>(&b);
>     //prints: B::f
>     //would like to have: A::f

    memb_fun_clbk<B, &B::non_virtual_f>(&b); // prints B::f

>   return 0;
>   }

The template is tricking you into thinking that this is a complicated
problem. In fact it is very simple. Remember that templates are not
the same as macros.

The second argument to the template, MF, is a member function pointer
to a virtual function. The call uses the virtual call mechanism. The
solution is to avoid the virtual call mechanism, as shown above.

--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: RafalD <rdzbek@impaq.com.pl>
Date: 1998/11/30
Raw View
The following program prints:
    A::f
    B::f.
I tried to force EGCS compiler to print
    A::f
    A::f
by changing the body of the function template from:
    (pObj->*MF)()
to:
    (pObj->*Class::MF)()
but the compiler failed:
    t.cpp: In function `void memb_fun_clbk<A, A::f()>(struct A *)':
    t.cpp:21:   instantiated from here
    t.cpp:6: `MF' is not a member of type `A'

MF is compile time constant (non-type template argument).
Is that deficiency of EGCS compiler or is the syntax incorrect?
Is there any other way to get expected behavior?


    Thanks,
        Rafal Dzbek (rdzbek@impaq.com.pl)

////////////////////////////////////////////////////////////////////////////
//////

#include <iostream>

template < typename Class, void (Class::*MF)() >
void memb_fun_clbk( Class* pObj )
  {
    return (pObj->*MF)();
  }

struct A
  {
  virtual void f() {std::cout << "\nA::f"; }
  };
struct B: A
  {
  virtual void f() {std::cout << "\nB::f"; }
  };

int main()
  {
  A a;
  memb_fun_clbk<A, &A::f>(&a);  //prints: A::f

  B b;
  memb_fun_clbk<A, &A::f>(&b);
    //prints: B::f
    //would like to have: A::f
  return 0;
  }










[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1998/11/30
Raw View
RafalD wrote:

> The following program prints:
>     A::f
>     B::f.
> I tried to force EGCS compiler to print
>     A::f
>     A::f

[ie make a static call using a pointer to function ]

> Is there any other way to get expected behavior?

Absolutly no way.

[ There is no need to post the same question in comp.std.c++
and comp.lang.c++.moderated at the same time (I mean post,
not cross-post). ]

[ moderator's note: Cross-posting articles is more work for the
  moderators, and can add up to two extra days for an article
  to appear in any newsgroup. We moderators recommend that you
  post in just the group that is most appropriate: "lang" for
  programming questions, "std" for standards questions. -sdc ]

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://pages.pratique.fr/~bonnardv/


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]