派生类中的模板方法优于非模板方法
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[]) { ... }
};
为什么调用此代码时函数 B::func()
not 优先于函数模板 A::func()
?
uint32_t values[5];
A* obj = new B();
obj->func(5, values);
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?
uint32_t values[5];
A* obj = new B();
obj->func(5, values);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
有两个原因
在 C++ 中,如果基类函数被标记为 virtual,则成员函数仅重写基类成员函数。否则,C++ 将这两个函数视为恰好具有相同名称的独立函数。这与 Java 形成对比,在 Java 中,函数自动重写基类函数。
在 C++ 中,模板成员函数不能标记为虚拟。这部分是由于最常用的虚拟函数(vtable)的实现与 C++ 模板实例化系统相结合。 C++ 将同一模板在不同类型参数上的所有实例化视为单独的函数,并延迟生成这些实例化。这对于 vtable 实现来说是一个问题,因为 vtable 需要静态、编译时确定类中不同虚拟函数的数量以及它们的排序。由于模板虚函数意味着类中虚函数的数量和顺序未知,因此 C++ 不允许这样做。
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.
如果您对
A
类型的对象/指针/引用调用func
,则会调用A::func
,因为func
code> 不是虚拟的(也不可能是:它是一个模板函数)。你真的测试过你的代码吗?
If you call
func
on a object/pointer/reference of typeA
,A::func
gets called, sincefunc
is not virtual (and it cannot be: it's a template function).Did you really test your code?
A::func()
未声明为virtual
,因此编译器不会生成虚拟表以及调用B:: 所需的任何其他代码func() 在运行时。它与模板无关。
A::func()
isn't declared asvirtual
, so the compiler won't generate the virtual table and any other code required to invokeB::func()
at runtime. It has nothing to do with templates.因为 B::func 不是 A::func 的重载,而且永远不可能,无论你做什么。甚至不要尝试将 A::func 声明为虚拟,因为你做不到。无论你想做什么,你都做不到。静态多态性和动态多态性在 C++ 中是不能混合的。
如果您的指针指向 B*,而不是 A*,您会期望调用它的版本。
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.