Re: Pointer to virtual method in child class as template parameter
Hi Stephan!
Stephan Tolksdorf <andorxor@gmx.de> writes:
Could maybe somebody explain why all the compilers (Comeau, GCC, MSVC)
I tested printed error messages similar to
"error: argument of type "void (A::*)()" is incompatible with template
parameter of type "BMethodPointer"
D<&B::doSomething> d;
^
"
when compiling the following code snippet.
[added below]
[...]
Is this a language "feature" or a surprisingly common bug?
This is indeed a language feature. The standard defines several
restrictions on conversions for template non-type arguments (14.3.2).
Relevant for your example is 14.3.2/5, the second to last bullet:
- For a nontype template-parameter of type pointer to member function,
no conversions apply. If the template-argument represents a set of
overloaded member functions, the matching member function is
selected from the set (13.4).
--
#include <iostream>
class A { // interface
public:
virtual void doSomething() = 0;
};
class B : public A { }; // extended interface
B does not declare doSomething(), so any reference or pointer to
B::doSomething actually refers to A::doSomething.
class C : public B { // implementation
virtual void doSomething() {
std::cout << "test";
}
};
typedef void (B::* BMethodPointer)();
template <BMethodPointer p>
class D {
D() { // constructor that calls p on a C instance
C c;
(c.*p)();
}
};
int main() {
BMethodPointer p = &B::doSomething; // this compiles
Here we have a "pointer to member" conversion according to 4.11/2.
C c;
(c.*p)();
D<&B::doSomething> d; // but this doesn't
No conversion because of 14.3.2/5.
}
--
You can get your code to work if you redeclare doSomething() in
class B (and make the constructor of class D public):
--
class A { // interface
public:
virtual void doSomething() = 0;
};
class B : public A {
virtual void doSomething() = 0;
}; // extended interface
--
Kind regards,
Stefan
--
PLEASE NOTE: Some Quantum Physics theories suggest that when the
consumer is not directly observing this product, it may cease to exist
or will exist only in a vague and undetermined state.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]