C++11 CRTP避免代码重复:can';t赋值基数=由值导出

C++11 CRTP避免代码重复:can';t赋值基数=由值导出,c++11,inheritance,polymorphism,crtp,C++11,Inheritance,Polymorphism,Crtp,我有Base、Derived1、Derived2等课程。 它是可编译的(见下文) 编辑:我相信是这样,我认为这与问题无关 然后,我希望操作符->()位于基中,这样我就不必在所有DerivedX类中实现 这是我迄今为止的尝试,使用CRTP。它在#处不可编译:- class Base{ }; template<class T1,class T2>class Helper{ public: T2* operator->() { return static_cast<T

我有
Base
Derived1
Derived2
等课程。
它是可编译的(见下文)

编辑:我相信是这样,我认为这与问题无关

然后,我希望
操作符->()
位于
基中,这样我就不必在所有
DerivedX
类中实现

这是我迄今为止的尝试,使用
CRTP
。它在
#
处不可编译:-

class Base{  };
template<class T1,class T2>class Helper{
    public: T2* operator->() { return static_cast<T2*>(this); }
};
class Derived1 : public Helper<Base,Derived1>{
    public: void f1(){}
};
class Derived2 : public Helper<Base,Derived2>{    };
class Derived3 : public Helper<Derived2,Derived3>{    };
int main(){
    Derived1 d1;  d1->f1();
    Base b=d1;                    //#
    Derived3 d3;     
    Derived2 d2=d3;
}
类基{};
模板类助手{
public:T2*运算符->(){返回静态_cast(this);}
};
类Derived1:公共助手{
public:void f1(){}
};
类Derived2:公共助手{};
类Derived3:公共助手{};
int main(){
衍生1 d1;d1->f1();
基准b=d1//#
衍生3 d3;
Derived2 d2=d3;
}
我已经阅读了这两个有希望的链接(见下文),但进展甚微(见上文):-

Wiki声明了这一点,所以我觉得可能没有使用CRTP的解决方案

问题:

  • 如何将
    运算符->
    移动到某种基类以避免代码重复?
    (带或不带CRTP都可以)
  • 有没有使用CRTP的解决方案?换句话说,CRTP是否不适合此工作

我是CRTP的新手(今天就玩吧)。抱歉,如果它重复了。

将对象的切片放在一边,如果将助手定义为:

template<class T1, class T2>
class Helper: public T1 {
public:
    T2* operator->() {
        return static_cast<T2*>(this);
    }
};

不用说,现在
Base b=d1
可以工作,因为
Derived1
直接继承自
Base

首先需要了解的是。那么对于您的问题,在第二个示例中,派生类不是从
Base
派生的。继承是一种“is-a”关系,但例如,
Derived1
不是
Base
,而是
Helper
@Some程序员关于“is-a”的问题:是的,wiki对此表示关注。我理解。这就像CRTP的一个直接缺点。有什么解决办法吗。。。。。。。关于对象切片:在这个特定的情况下,我不害怕切片(主要)。我承认我得到了一些警告。:)解决方法是修改
Base
类。不要发明一些
助手
类。但是它仍然不能与
b
对象的初始化一起工作,因为
b
不是
Derived1
对象,而是
Base
对象,所以转换将是错误的。如果你尝试
b->f1()
,你将有未定义的行为(如果它甚至生成)。@一些程序员伙计,谢谢!顺便说一下,我想要的是
d1->f1()
而不是
b->f1()
。我只想要上抛。抱歉,如果我的变量名令人困惑。请将
Helper
派生自
T1
-然后
Derived1
等实际上将派生自
Base
(间接)。不过,我不清楚
Base
类的目的是什么,以及为什么所有
DerivedX
都继承自它很重要。这需要时间来消化,但我坚信这是一个正确的解决方案。这种CRTP方法是否有任何特定的技术术语。。。看起来很酷,为什么很难消化?您需要一个从第一个模板参数继承的中间类模板,并使用第二个模板参数添加crtp内容。你只是忘了从第一步走到最后。
T1
的目的是什么?在你的例子中是没有用过的,对吗?同意,我只是觉得头晕。XD@javaLover啊哈。这是常有的事。不管怎样,这个习语被称为mixin或继承自上。你把它和crtp弄混了,正如答案中提到的。哇,谢谢。我刚刚找到了自己的。
template<class T1, class T2>
class Helper: public T1 {
public:
    T2* operator->() {
        return static_cast<T2*>(this);
    }
};
class Derived1: public Helper<Base, Derived1>;