CRTP 以避免代码重复:不能赋值 Base=Derived by value

CRTP to avoid code duplication : can't assignment Base=Derived by value

我有 classes BaseDerived1Derived2
它是可编译的(如下)。

class Base{  };
class Derived1 : public Base{
    public: Derived1* operator->() { return this; }
    public: void f1(){}
};
class Derived2 : public Base{
    public: Derived2* operator->() { return this; }
};
class Derived3 : public Derived2{
    public: Derived3* operator->() { return this; }
};
int main(){//test case (my objective is to make all these work)
    Derived1 d1;  d1->f1();
    Base b=d1;              //non harmful object slicing
    Derived3 d3;
    Derived2 d2=d3;
}

编辑:我认为是a non-harmful object slicing,我认为它与问题无关。

然后,我希望 operator->() 位于 Base 内,这样我就不必全部实现 DerivedX class.

这是我迄今为止的尝试,使用 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;
}

我已经阅读了这两个有希望的链接(下方),但进展甚微(上方):-

Wiki 指出转换 Derive to Base is quite impossible for CRTP,所以我觉得可能没有使用 CRTP 的解决方案。

问题:

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

撇开对象的切片不谈,如果您将助手定义为:

,您的示例就可以正常工作
template<class T1, class T2>
class Helper: public T1 {
public:
    T2* operator->() {
        return static_cast<T2*>(this);
    }
};

即:

  • T1 派生,就像在基于纯 mixin 的方法中一样
  • 像在纯 CRTP 方法中一样使用T2

如果你考虑Derived1的声明:

class Derived1: public Helper<Base, Derived1>;

不言而喻,现在 Base b = d1; 有效,因为 Derived1 直接继承自 Base