Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Cannot match void (T::* ptr)() when base class of T defines function

Reply
Thread Tools

Cannot match void (T::* ptr)() when base class of T defines function

 
 
Firstname Lastname
Guest
Posts: n/a
 
      02-25-2005
In a function call, for example function(Class(), &Class::memfunc), my
compiler cannot match the 2nd argument when: (1) Class is a template
parameter, and (2) the base class of Class defines memfunc but Class itself
does not.

Is this the correct behavior? Second, are there any workarounds?


Consider the following program, which has a compile error in the last line
silly(b, &B::f).


#include <iostream>
#include <typeinfo>

using std::cout;


struct A
{
A() { }
void f() const { cout << "A::f()\n"; }
};

struct B : A
{
};

template <class T>
void silly(const T& t, void (T::* ptr)() const)
{
(t.*ptr)();
}

int main(int argc, char const *const * argv, char const *const * env)
{
const A a;
silly(a, &A::f);

const B b;
silly(b, &B::f); // compile error: can't match silly(const B&, void
(A::*)())
}



If we replace the

template <class T>
void silly(const T& t, void (T::* ptr)() const)

with

void silly(const B& t, void (B::* ptr)() const)

then the last line compiles fine.


 
Reply With Quote
 
 
 
 
Martijn Mulder
Guest
Posts: n/a
 
      02-25-2005
Firstname Lastname wrote:
> In a function call, for example function(Class(),
> &Class::memfunc), my compiler cannot match the 2nd
> argument when: (1) Class is a template parameter, and (2)
> the base class of Class defines memfunc but Class itself
> does not.
>
> Is this the correct behavior? Second, are there any
> workarounds?
>
>
> Consider the following program, which has a compile error
> in the last line silly(b, &B::f).
>
>
> #include <iostream>
> #include <typeinfo>
>
> using std::cout;
>
>
> struct A
> {
> A() { }
> void f() const { cout << "A::f()\n"; }
> };
>
> struct B : A
> {
> };
>
> template <class T>
> void silly(const T& t, void (T::* ptr)() const)
> {
> (t.*ptr)();
> }
>
> int main(int argc, char const *const * argv, char const
> *const * env) {
> const A a;
> silly(a, &A::f);
>
> const B b;
> silly(b, &B::f); // compile error: can't match
> silly(const B&, void (A::*)())
> }
>
>
>
> If we replace the
>
> template <class T>
> void silly(const T& t, void (T::* ptr)() const)
>
> with
>
> void silly(const B& t, void (B::* ptr)() const)
>
> then the last line compiles fine.




When you replace the last call to silly() in main to

silly((A)b, &B::f); // cast b to type A

your code does compile. Silly and useless


 
Reply With Quote
 
 
 
 
Martijn Mulder
Guest
Posts: n/a
 
      02-25-2005
Martijn Mulder wrote:
> Firstname Lastname wrote:
>> In a function call, for example function(Class(),
>> &Class::memfunc), my compiler cannot match the 2nd
>> argument when: (1) Class is a template parameter, and (2)
>> the base class of Class defines memfunc but Class itself
>> does not.
>>
>> Is this the correct behavior? Second, are there any
>> workarounds?
>>
>>
>> Consider the following program, which has a compile error
>> in the last line silly(b, &B::f).
>>
>>
>> #include <iostream>
>> #include <typeinfo>
>>
>> using std::cout;
>>
>>
>> struct A
>> {
>> A() { }
>> void f() const { cout << "A::f()\n"; }
>> };
>>
>> struct B : A
>> {
>> };
>>
>> template <class T>
>> void silly(const T& t, void (T::* ptr)() const)
>> {
>> (t.*ptr)();
>> }
>>
>> int main(int argc, char const *const * argv, char const
>> *const * env) {
>> const A a;
>> silly(a, &A::f);
>>
>> const B b;
>> silly(b, &B::f); // compile error: can't match
>> silly(const B&, void (A::*)())
>> }
>>
>>
>>
>> If we replace the
>>
>> template <class T>
>> void silly(const T& t, void (T::* ptr)() const)
>>
>> with
>>
>> void silly(const B& t, void (B::* ptr)() const)
>>
>> then the last line compiles fine.

>
>
>
> When you replace the last call to silly() in main to
>
> silly((A)b, &B::f); // cast b to type A
>
> your code does compile. Silly and useless



On second thought, silly, yes, but not useless. It's a _reference_, so virtual
function invoked on the object will behave correctly.


 
Reply With Quote
 
Siemel Naran
Guest
Posts: n/a
 
      02-26-2005
"Martijn Mulder" <i@m> wrote in message news:421f24a8$0$51221
> Firstname Lastname wrote:


> > #include <iostream>
> > #include <typeinfo>
> >
> > using std::cout;
> >
> >
> > struct A
> > {
> > A() { }
> > void f() const { cout << "A::f()\n"; }
> > };
> >
> > struct B : A
> > {
> > };
> >
> > template <class T>
> > void silly(const T& t, void (T::* ptr)() const)
> > {
> > (t.*ptr)();
> > }
> >
> > int main(int argc, char const *const * argv, char const
> > *const * env) {
> > const A a;
> > silly(a, &A::f);
> >
> > const B b;
> > silly(b, &B::f); // compile error: can't match
> > }


> When you replace the last call to silly() in main to
>
> silly((A)b, &B::f); // cast b to type A
>
> your code does compile. Silly and useless


OK. But is this slicing (meaning the B only part gets sliced away because
we're converting a B object to an A object)? In my real example function
f() is indeed not virtual, but it calls a protected virtual function, and
furthermore class A is abstract. Thinking along your line, I suppose one
could use static cast

silly(static_cast<const A&>(b), &A::f);

Would this work? No time yet to compile it, will try later.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the difference between void proba(); and void proba(void); ??? PencoOdStip@gmail.com C++ 1 05-23-2007 07:12 PM
what is the difference, void func(void) and void fucn() noblesantosh@yahoo.com C Programming 5 07-22-2005 04:38 PM
"void Method()" vs "void Method(void)" Ollej Reemt C++ 7 04-22-2005 03:47 AM
How to define a define that defines some defines ? theotyflos C Programming 3 02-19-2004 05:07 PM
`void **' revisited: void *pop(void **root) Stig Brautaset C Programming 15 10-28-2003 09:03 AM



Advertisments