Suppose that we have the following base and derived classes:
#include <string>
#include <iostream>
class Car {
public:
void Drive() { std::cout << "Baby, can I drive your car?" << std::endl; }
};
class Porsche : public Car {
};
..and also the following template function:
template <typename T, typename V>
void Function(void (T::*m1)(void), void (V::*m2)(void)) {
std::cout << (m1 == m2) << std::endl;
}
Why does this compile using GCC:
int main(int argc, char** argv) {
void (Porsche::*ptr)(void) = &Porsche::Drive;
Function(ptr, ptr);
return 0;
}
...but not this?
int main(int argc, char** argv) {
void (Porsche::*ptr)(void) = &Porsche::Drive;
Function(&Porsche::Drive, ptr);
return 0;
}
int main(int argc, char** argv) {
void (Porsche::*ptr)(void) = &Porsche::Drive;
Function(&Porsche::Drive, ptr);
return 0;
}
ptr
has type void (Porsche::*)()
, but &Porsche::Drive
has type void (Car::*)()
(because the member is found in Car
, not in Porsche
). Thus the function called compares these two member pointers with those types, and the standard says
In addition, pointers to members can be compared, or a pointer to member and a null pointer constant. Pointer to member conversions (4.11) and qualification conversions (4.4) are performed to bring them to a common type. If one operand is a null pointer constant, the common type is the type of the other operand. Otherwise, the common type is a pointer to member type similar (4.4) to the type of one of the operands, with a cv-qualification signature (4.4) that is the union of the cv-qualification signatures of the operand types.
4.11
describes an implicit Standard conversion from void (Base::*)()
to void (Derived::*)()
. Thus, the comparison would find the common type void (Porsche::*)()
. For an object of type Porsche
, both member pointers would refer to the same function (which is Car::Drive
) - so the comparison would yield true. The comeau web compiler follows this interpretation and compiles your code.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With