欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

类成员函数模板可以是虚拟的吗?

程序员文章站 2024-03-21 10:08:22
...

本文翻译自:Can a class member function template be virtual?

I have heard that C++ class member function templates can't be virtual. 我听说C ++类成员函数模板不能是虚拟的。 Is this true? 这是真的?

If they can be virtual, what is an example of a scenario in which one would use such a function? 如果它们可以是虚拟的,那么使用这种功能的场景的例子是什么?


#1楼

参考:https://stackoom.com/question/9Sr8/类成员函数模板可以是虚拟的吗


#2楼

不可以,模板成员函数不能是虚拟的。


#3楼

Templates are all about the compiler generating code at compile-time . 模板都是关于编译器在编译时生成代码的。 Virtual functions are all about the run-time system figuring out which function to call at run-time . 虚拟函数都是关于运行时系统的,找出要在运行时调用哪个函数。

Once the run-time system figured out it would need to call a templatized virtual function, compilation is all done and the compiler cannot generate the appropriate instance anymore. 一旦确定了运行时系统,它将需要调用模板化的虚拟函数,编译全部完成,并且编译器无法再生成适当的实例。 Therefore you cannot have virtual member function templates. 因此,您不能具有虚拟成员功能模板。

However, there are a few powerful and interesting techniques stemming from combining polymorphism and templates, notably so-called type erasure . 但是,结合多态性和模板可以使用一些强大而有趣的技术,尤其是所谓的类型擦除


#4楼

C++ doesn't allow virtual template member functions right now. C ++目前不允许虚拟模板成员函数。 The most likely reason is the complexity of implementing it. 最可能的原因是实施它的复杂性。 Rajendra gives good reason why it can't be done right now but it could be possible with reasonable changes of the standard. 拉金德拉(Rajendra)给出了目前无法完成的充分理由,但可以通过合理更改标准来实现。 Especially working out how many instantiations of a templated function actually exist and building up the vtable seems difficult if you consider the place of the virtual function call. 如果考虑虚拟函数调用的位置,特别是要计算出实际上存在多少个模板化函数实例化并建立vtable似乎很困难。 Standards people just have a lot of other things to do right now and C++1x is a lot of work for the compiler writers as well. 标准人们现在还有很多其他事情要做,C ++ 1x对于编译器编写者来说也是很多工作。

When would you need a templated member function? 什么时候需要模板成员函数? I once came across such a situation where I tried to refactor a hierarchy with a pure virtual base class. 我曾经遇到过这样的情况,我试图用纯虚拟基类重构层次结构。 It was a poor style for implementing different strategies. 实施不同策略的风格很差。 I wanted to change the argument of one of the virtual functions to a numeric type and instead of overloading the member function and override every overload in all sub-classes I tried to use virtual template functions (and had to find out they don't exist.) 我想将其中一个虚拟函数的参数更改为数值类型,而不是重载成员函数并覆盖所有试图使用虚拟模板函数的所有子类中的每个重载(并且不得不发现它们不存在) )


#5楼

From C++ Templates The Complete Guide: 从C ++模板完整指南:

Member function templates cannot be declared virtual. 成员函数模板不能声明为虚拟。 This constraint is imposed because the usual implementation of the virtual function call mechanism uses a fixed-size table with one entry per virtual function. 由于虚拟函数调用机制的通常实现使用固定大小的表,每个虚拟函数只有一个条目,因此施加了此约束。 However, the number of instantiations of a member function template is not fixed until the entire program has been translated. 但是,成员函数模板的实例化数目直到翻译完整个程序后才确定。 Hence, supporting virtual member function templates would require support for a whole new kind of mechanism in C++ compilers and linkers. 因此,支持虚拟成员函数模板将需要支持C ++编译器和链接器中的一种全新的机制。 In contrast, the ordinary members of class templates can be virtual because their number is fixed when a class is instantiated 相反,类模板的普通成员可以是虚拟的,因为在实例化一个类时其数目是固定的


#6楼

The following code can be compiled and runs properly, using MinGW G++ 3.4.5 on Window 7: 在Windows 7上使用MinGW G ++ 3.4.5,可以编译并正确运行以下代码:

#include <iostream>
#include <string>

using namespace std;

template <typename T>
class A{
public:
    virtual void func1(const T& p)
    {
        cout<<"A:"<<p<<endl;
    }
};

template <typename T>
class B
: public A<T>
{
public:
    virtual void func1(const T& p)
    {
        cout<<"A<--B:"<<p<<endl;
    }
};

int main(int argc, char** argv)
{
    A<string> a;
    B<int> b;
    B<string> c;

    A<string>* p = &a;
    p->func1("A<string> a");
    p = dynamic_cast<A<string>*>(&c);
    p->func1("B<string> c");
    B<int>* q = &b;
    q->func1(3);
}

and the output is: 输出为:

A:A<string> a
A<--B:B<string> c
A<--B:3

And later I added a new class X: 然后我添加了一个新的类X:

class X
{
public:
    template <typename T>
    virtual void func2(const T& p)
    {
        cout<<"C:"<<p<<endl;
    }
};

When I tried to use class X in main() like this: 当我尝试在main()中使用X类时:

X x;
x.func2<string>("X x");

g++ report the following error: g ++报告以下错误:

vtempl.cpp:34: error: invalid use of `virtual' in template declaration of `virtu
al void X::func2(const T&)'

So it is obvious that: 因此很明显:

  • virtual member function can be used in a class template. 虚拟成员函数可以在类模板中使用。 It is easy for compiler to construct vtable 编译器构造vtable很容易
  • It is impossible to define a class template member function as virtual, as you can see, it hard to determine function signature and allocate vtable entries. 如您所见,将类模板成员函数定义为虚函数是不可能的,很难确定函数签名和分配vtable条目。