What happens in parameterized virtuality?

為{幸葍}努か 提交于 2021-02-08 10:48:14

问题


Chapter 16.4 Parameterized Virtuality in the C++ Templates - The Complete Guide, by David Vandevoorde and Nicolai M. Josuttis, says:

C++ allows us to parameterize directly three kinds of entities through templates: types, constants ("nontypes"), and templates. However, indirectly, it also allows us to parameterize other attributes such as the virtuality of a member function.

The following code was illustrated in that chapter:

#include <iostream>

struct NotVirtual
{};

struct IsVirtual
{
    virtual void func() {;}
};

//---------------------//

template<typename T>
struct Base : T
{
    void func()
    { std::cout<< "Base::func()" <<std::endl; }
};

template<typename T>
struct Derived : Base<T>
{
    void func()
    { std::cout<< "Derived::func()" <<std::endl; }
};

//---------------------//

int main()
{
    Base<NotVirtual> *p1 = new Derived<NotVirtual>();
    p1->func();
    delete p1;

    Base<IsVirtual> *p2 = new Derived<IsVirtual>();
    p2->func();
    delete p2;
}

Example online: https://rextester.com/OAGC66937

I understand the usage of such a technique, but unfortunately the book does not provide any further details as to how this thing happens. I can see that Base is actually a derived class inheriting from the template parameter T.

Questions:

  1. What happens in the background during parameterized virtuality?
  2. Does something happen in the resulting v_table?
  3. How does the virtual from the template parameter get transferred over?

回答1:


To expand upon @Quentin's comment

Once the Base template is specialized for a specific T, everything proceeds as usual through inheritance and virtual overriding.

Let's write out an equivalent non-template set of classes

struct BaseNV : NotVirtual
{
    void func() // first definition of func
    { std::cout<< "Base::func()" <<std::endl; }
};

struct DerivedNV : BaseNV 
{
    void func() // hides BaseNV::func
    { std::cout<< "Derived::func()" <<std::endl; }
};

struct BaseIV : IsVirtual
{
    void func() // implicitly virtual, overrides IsVirtual::func
    { std::cout<< "Base::func()" <<std::endl; }
};

struct DerivedIV : BaseIV
{
    void func() // implicitly virtual, overrides BaseIV::func (and IsVirtual::func)
    { std::cout<< "Derived::func()" <<std::endl; }
};

int main()
{
    BaseNV *p1 = new DerivedNV();
    p1->func();
    delete p1;

    BaseIV *p2 = new DerivedIV();
    p2->func();
    delete p2;
}

See it live

What happens in the background during parameterized virtuality?

Base<T> inherits from T, and follows the rules of inheritance

Does something happen in the resulting v_table?

Only the ordinary virtual mechanisms. Specifically, in the NotVirtual case there aren't any virtual functions, so there probably won't be any vtables.

How does the virtual from the template parameter get transferred over?

By the normal rules of inheritance



来源:https://stackoverflow.com/questions/55472947/what-happens-in-parameterized-virtuality

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!