Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!att!dptg!ulysses!andante!alice!ark From: ark@alice.UUCP (Andrew Koenig) Newsgroups: comp.lang.c++ Subject: Re: pointers to member functions Message-ID: <10206@alice.UUCP> Date: 2 Dec 89 15:31:46 GMT References: <950@sl10c.concurrent.co.uk> Organization: AT&T Bell Laboratories, Liberty Corner NJ Lines: 46 In article <950@sl10c.concurrent.co.uk>, asc@concurrent.co.uk (Andy Chittenden) writes: [example that declares `dispatcher' as taking a pointer to a member of class `base' > dispatcher a(base::fn1); > dispatcher b(derived::fn2); // fails to compile under v2 > // I can understand why the second line does not compile (derived::fn2 > // is not a function of base). However, how is one meant to achieve the > // above effect under v2 (pass an arbitrary function of a derived class > // with matching parameters)? The `dispatcher' function takes a pointer to a member of class `base.' There may be some members of class `derived' that are not members of class `base,' so you can't pass any member of `derived' to a function that takes a pointer to a member of `base' as its argument. In particular, if fn2 were a member of `base' you would have been able to say dispatcher b(base::fn2); and there would have been no problem. Watch this, though. Every member of class `base' is also a member of class `derived.' Therefore you CAN pass a member of class `base' to a function that expects a pointer to a member of class `derived'! Example: void f(int (derived::*)(int)); main() { f(derived::fn2); // OK f(base::fn1); // also OK! } This may seem backwards at first, but if you think about it for a while you will see that it has to be this way, version 1 to the contrary notwithstanding. This phenomenon is often called `contravariance.' -- --Andrew Koenig ark@europa.att.com