Template method over non-template method in derived class
class A {
public:
template<typename T> void func(size_t n, T values[]) { ... }
};
clas开发者_如何学Gos B : public A {
public:
void func(size_t n, uint32_t values[]) { ... }
};
Why does function B::func()
not take precedence over the function template A::func()
when calling this code?
uint32_t values[5];
A* obj = new B();
obj->func(5, values);
Two reasons-
In C++ a member function only overrides a base class member function if the base class function is marked virtual. Otherwise, C++ treats the two as independent functions that coincidentally have the same name. This contrasts with Java, where functions atomatically override base class functions.
In C++, template member functions can't be marked virtual. This is partly due to the implementation of virtual functions that's most commonly used - vtables - combined with the C++ template instantiations system. C++ treats all instantiations of the same template over different type arguments as separate functions, and generates these instantiations lazily. This is a problem for the vtable implementation, since a vtable requires static, compile-time determination of the number of different virtual functions in a class, along with an ordering on them. Since a template virtual function would mean an unknown number and ordering of virtual functions in the class, C++ disallows this.
If you call func
on a object/pointer/reference of type A
, A::func
gets called, since func
is not virtual (and it cannot be: it's a template function).
Did you really test your code?
A::func()
isn't declared as virtual
, so the compiler won't generate the virtual table and any other code required to invoke B::func()
at runtime. It has nothing to do with templates.
Because B::func is NOT an overload of A::func and can never be, no matter what you do. Don't even try declaring A::func virtual because you can't. Whatever it is you're trying to do, you can't. Static and dynamic polymorphism just don't mix in C++.
If your pointer was to a B*, instead of an A*, you would expect it's version to be called.
精彩评论