首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >继承和CRTP

继承和CRTP
EN

Stack Overflow用户
提问于 2013-03-10 06:35:12
回答 1查看 553关注 0票数 1

出于实际原因,我有一个类似这样的类

代码语言:javascript
复制
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)()>是必需的,不能作为参数传递。

我也有一个类库

代码语言:javascript
复制
class Base : public CRTP<Base>
{
    int aMemberOfBase() {...}
};

和它的派生,我还想继承CRTP

代码语言:javascript
复制
class Derived : public CRTP<Derived>, public Base
{
    int aMemberOfDerived() {...}
};

在某个派生成员中,我将执行如下操作

代码语言:javascript
复制
func<&Derived::aMemberOfDerived>(this);
func<&Base::aMemberOfBase>(this);

这有可能吗?

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

代码语言:javascript
复制
template <int (Base::*Member)()> int func(void * obj);
template <int (Derived::*Member)()> int func(void * obj);

我承认这看起来很奇怪。但是下面这段代码

代码语言:javascript
复制
template <void (Base::*Member)()> int func() {return 0;}
template <void (Derived::*Member)()> int func() {return 1;}

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

我必须承认我对标准所说的并不是很了解。但是我试图创建的继承模式是允许的吗?如果是,为什么其中一行不能编译?

此外,如果我宣布

代码语言:javascript
复制
class Derived : public Base, public CRTP<Derived>

而不是

代码语言:javascript
复制
class Derived : public CRTP<Derived>, public Base

我得到了编译时错误(在所有的func<...>(...)上),这意味着有什么地方出了问题。

另一方面,我知道

代码语言:javascript
复制
template <class A, int (A::*Member)()> int func(void * obj)

将不再需要CRTP,但是编写func<Derived, &Derived::aMember>()很痛苦。有像这样的变通方法吗?

代码语言:javascript
复制
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)

EN

回答 1

Stack Overflow用户

发布于 2013-03-10 06:46:04

您可以通过限定基本成员模板的名称来消除歧义。下面的代码应该可以工作:

代码语言:javascript
复制
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>();
    }
};

我公开了所有内容,以避免陷入访问控制细节的泥潭。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15316699

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档