假设我具有以下使用经典继承的简单类层次结构:
struct A_classic {};
struct B_classic : A_classic {};
我想实现从
A_classic
到B_classic
的转换运算符。要重用尽可能多的代码,我会A_classic a; // Given as input argument
B_classic b;
static_cast<A_classic&>(b) = a; // Copy A_classic's members
// Now set up B_classic's members
问题是实际上我在使用CRTP进行继承:
template<class Derived> struct A_crtp_base {};
struct A_crtp : A_crtp_base<A_crtp> {};
template<class Derived> struct B_crtp_base : A_crtp_base<B_crtp_base<Derived>> {};
struct B_crtp : B_crtp_base<B_crtp> {};
上面的技巧不再起作用,因为
A_crtp
,B_crtp
的“通用”基类分别是A_crtp_base<A_crtp>
和A_crtp_base<B_crtp>
。A_crtp a;
B_crtp b;
static_cast<A_crtp_base<???>&>(b) = a;
// No matter what I put here, either the cast or the assignment will fail
一个明显的解决方案是对
A_crtp_base
的副本构造函数进行模板化:template<class Derived>
struct A_crt_base {
template<class OtherDerived>
A_crtp_base(const A_crtp_base<OtherDerived>& other);
}
但是然后我必须编写自己的副本构造函数,这是我想避免的。
有什么建议可以减少此处的编码量吗?
最佳答案
您可以将自己的转换运算符定义为常见的A_crtp_base
类
struct B_crtp;
template<class Derived> struct B_crtp_base;
template<class Derived>
struct A_crtp_base {
operator B_crtp_base<B_crtp>();
};
struct A_crtp : A_crtp_base<A_crtp> {
};
template<class Derived> struct B_crtp_base : A_crtp_base<B_crtp_base<Derived>> {};
struct B_crtp : B_crtp_base<B_crtp> {};
template<class Derived>
A_crtp_base<Derived>::operator B_crtp_base<B_crtp>()
{
return B_crtp_base<B_crtp>(); // Whatever, make sure this is set with common A_crtp_base stuff
}
int main()
{
A_crtp a;
B_crtp b;
static_cast< B_crtp_base<B_crtp>& >(b) = a;
return 0;
}
Example
一个小建议:如果可能,尝试稍微简化层次结构,如果需要简单的继承机制,则将迫使编译器处理不同类型的对象,并使事情可能比它们复杂得多。
关于c++ - 从CRTP到衍生转化,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26054006/