继承和CRTP

时间:2013-03-09 22:35:12

标签: c++ inheritance crtp

出于实际原因,我有一个像

这样的课程
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;
    }
};

template <void (A::*Member)()>是一项要求,不能作为参数传递。

我还有一个班级基地

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

它的派生我想继承CRTP

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

在Derived的某些成员中,我会做类似

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

这可能吗?

(好吧,VC ++只编译第一行,不想读第二行......但Derived应该有成员

template <int (Base::*Member)()> int func(void * obj);
template <int (Derived::*Member)()> int func(void * obj);
我承认,这看起来很奇怪。但是下面的一段代码

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

编译并返回func<&Base::someMember>() != func<&Derived::someMember>(),因为模板的签名不一样且不能相同。)

我必须承认,我不能很好地评价标准所说的内容。但是我试图允许的继承模式是什么?如果是,为什么其中一行不能编译?

此外,如果我宣布

class Derived : public Base, public CRTP<Derived>

而不是

class Derived : public CRTP<Derived>, public Base

我得到编译时错误(在所有func<...>(...)上),这意味着某处出现了错误。

另一方面,我知道

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

会删除CRTP的需要,但编写func<Derived, &Derived::aMember>()会很痛苦。有没有像

这样的解决方法
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> {};

允许B<&Base::Derived>().func(somePtrToBase)

1 个答案:

答案 0 :(得分:1)

您可以通过限定基本成员模板的名称来消除歧义。以下应该有效:

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>();
    }
};

我公开了一切,以避免陷入访问控制细节。