简体   繁体   English

派生类中非模板方法的模板方法

[英]Template method over non-template method in derived class

class A {
public:
    template<typename T> void func(size_t n, T values[]) { ... }
};

class 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? 为什么函数B::func() A::func()在调用此代码时优先于函数模板A::func()

uint32_t values[5];
A* obj = new B();
obj->func(5, values);

Two reasons- 两个原因 -

  1. In C++ a member function only overrides a base class member function if the base class function is marked virtual. 在C ++中,如果基类函数标记为虚拟,则成员函数仅覆盖基类成员函数。 Otherwise, C++ treats the two as independent functions that coincidentally have the same name. 否则,C ++将两者视为巧合具有相同名称的独立函数。 This contrasts with Java, where functions atomatically override base class functions. 这与Java形成对比,Java中的函数自动覆盖基类函数。

  2. In C++, template member functions can't be marked virtual. 在C ++中,模板成员函数不能标记为虚拟。 This is partly due to the implementation of virtual functions that's most commonly used - vtables - combined with the C++ template instantiations system. 这部分是由于最常用的虚函数的实现 - vtables - 与C ++模板实例化系统相结合。 C++ treats all instantiations of the same template over different type arguments as separate functions, and generates these instantiations lazily. C ++将不同类型参数的同一模板的所有实例化视为单独的函数,并且懒惰地生成这些实例化。 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. 这是vtable实现的一个问题,因为vtable需要静态编译时确定类中不同虚函数的数量,以及对它们的排序。 Since a template virtual function would mean an unknown number and ordering of virtual functions in the class, C++ disallows this. 由于模板虚函数意味着类中未知的数字和虚函数的排序,C ++不允许这样做。

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). 如果在类型A的对象/指针/引用上调用func ,则会调用A::func ,因为func不是虚拟的(并且它不能是:它是模板函数)。

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. A::func()未声明为virtual ,因此编译器不会生成虚拟表以及在运行时调用B::func()所需的任何其他代码。 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. 因为B :: func不是A :: func的重载,无论你做什么都不可能。 Don't even try declaring A::func virtual because you can't. 甚至不要尝试声明A :: func虚拟,因为你不能。 Whatever it is you're trying to do, you can't. 无论你想做什么,你都做不到。 Static and dynamic polymorphism just don't mix in C++. 静态和动态多态只是不混合在C ++中。

If your pointer was to a B*, instead of an A*, you would expect it's version to be called. 如果你的指针是B *,而不是A *,你会期望它的版本被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM