简体   繁体   English

继承和CRTP

[英]Inheritance and CRTP

For practical reasons, I've got a class like 出于实际原因,我上了一堂课

template <class A>
class CRTP
{
    template <int (A::*Member)()>
    int func(void * obj)
    {
        int result
        // Do something with Member, like
        // result = (reinterpret_cast<A*>(obj)->*Member)();
        return result;
    }
};

The template <void (A::*Member)()> is a requirement, it cannot be passed as an argument. template <void (A::*Member)()>是必需的,不能作为参数传递。

And I also have a class Base 我也有一个基础班

class Base : public CRTP<Base>
{
    int aMemberOfBase() {...}
};

And its derived which I want to also inherit CRTP 及其派生我也想继承CRTP

class Derived : public CRTP<Derived>, public Base
{
    int aMemberOfDerived() {...}
};

In some member of Derived, I'll do something like 在“派生”的某个成员中,我会做类似的事情

func<&Derived::aMemberOfDerived>(this);
func<&Base::aMemberOfBase>(this);

Is that possible ? 那可能吗 ?

(Well, VC++ compile only the first line and don't want to read about the second one... but Derived should have the members (好吧,VC ++只编译第一行,不想阅读第二行...但是Derived应该有成员

template <int (Base::*Member)()> int func(void * obj);
template <int (Derived::*Member)()> int func(void * obj);

which looks strange, I admit it. 我承认这看起来很奇怪。 But the following piece of code 但是下面的代码

template <void (Base::*Member)()> int func() {return 0;}
template <void (Derived::*Member)()> int func() {return 1;}

compiles and return func<&Base::someMember>() != func<&Derived::someMember>() , because the signature of the template is not the same and can't be the same.) 编译并返回func<&Base::someMember>() != func<&Derived::someMember>() ,因为模板的签名不相同并且不能相同。)

I must admit that I'm not well award of what the standard says. 我必须承认,我对标准所说的不满意。 But is the inheritance pattern I'm trying to make allowed? 但是我要允许的继承模式是否被允许? And if yes, why one of the line doesn't compile? 如果是,为什么其中一行不能编译?

Moreover, if I declare 而且,如果我声明

class Derived : public Base, public CRTP<Derived>

instead of 代替

class Derived : public CRTP<Derived>, public Base

I get compile time error (on all the func<...>(...) ), which means that there's something wrong somewhere. 我收到编译时错误(在所有func<...>(...) ),这意味着某处出了点问题。

On the other hand, I know that 另一方面,我知道

template <class A, int (A::*Member)()> int func(void * obj)

would remove the need of a CRTP, but it's painfull to write func<Derived, &Derived::aMember>() . 会消除对CRTP的需求,但是编写func<Derived, &Derived::aMember>()很痛苦。 Is there a workaround like 是否有类似的解决方法

template <class Class, void (Class::*Member)()> class A 
{
    void func(void * obj) {...(reinterpret_cast<Class*>(obj)->*Member)();...} 
};
template <typename Signature> class B;

template <typename Class, typename Member>
class B<&Class::Member> : public class A<Class, &Class::Member> {};

which would allow B<&Base::Derived>().func(somePtrToBase) ? 这将允许B<&Base::Derived>().func(somePtrToBase)吗?

You can disambiguate by qualifying the name of the base member template. 您可以通过限定基本成员模板的名称来消除歧义。 The following should work: 以下应该工作:

template <typename A> struct CRTP
{
    template <int (A::*Member)()> int func();
};

struct Base : CRTP<Base>
{
    int aMemberOfBase();
};

struct Derived : CRTP<Derived>, Base
{
    int aMemberOfDerived();

    void foo()
    {
        CRTP<Derived>::func<&Derived::aMemberOfDerived>();
        CRTP<Base>::func<&Base::aMemberOfBase>();
    }
};

I made everything public to avoid getting bogged down in access control details. 我公开了所有内容,以避免陷入访问控制细节中。

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

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