Virtual inheritance and static inheritance - mixing in C++

前端 未结 6 677
误落风尘
误落风尘 2020-12-29 13:33

If you have something like this:

#include 

template class A
{
public:
    void func()
    {
        T::func();
    }
};

c         


        
6条回答
  •  生来不讨喜
    2020-12-29 14:21

    I'm not sure I understand what you're asking, but it appears you are missing the essential CRTP cast:

    template
    struct A {
      void func() {
        T& self = *static_cast(this);  // CRTP cast
        self.func();
      }
    };
    
    struct V : A {  // B for the case of virtual func
      virtual void func() {
        std::cout << "V::func\n";
      }
    };
    
    struct NV : A {  // B for the case of non-virtual func
      void func() {
        std::cout << "NV::func\n";
      }
    };
    

    If T does not declare its own func, this will be infinite recursion as self.func will find A::func. This is true even if a derived class of T (e.g. DV below) declares its own func but T does not.

    Test with different final overrider to show dispatch works as advertised:

    struct DV : V {
      virtual void func() {
        std::cout << "DV::func\n";
      }
    };
    struct DNV : NV {
      void func() {
        std::cout << "DNV::func\n";
      }
    };
    
    template
    void call(A& a) {
      a.func();  // always calls A::func
    }
    
    int main() {
      DV dv;
      call(dv);   // uses virtual dispatch, finds DV::func
      DNV dnv;
      call(dnv);  // no virtual dispatch, finds NV::func
    
      return 0;
    }
    

提交回复
热议问题