继承泛型成员函数
Inheriting generic member functions
我正在尝试将模板化成员函数的定义和声明从基类转移到派生类。问题是这些函数中的一些行为取决于类,基本上是静态多态性。我被建议使用 CRTP,它在大多数情况下效果很好。但是,如果我想从已经从我的 CRTP 基类继承的类继承,我遇到了问题。请考虑以下代码:
template<typename Derived>
struct CRTP
{
template<typename TypeRHS>
Derived& operator+=(const TypeRHS& rhs)
{
// do something
return static_cast<Derived&>(*this);
}
};
template<typename T>
struct Derived : public CRTP<Derived<T>> {};
template<typename T>
struct DerivedDerived : public Derived<T> {};
如果我在DerivedDerived<T>
上调用+=
,它将返回一种Derived<T>
。有没有办法解决这个问题。我只是想避免在所有类中重新声明/重新定义所有成员函数。就自由函数而言,我刚刚模板化了这些函数,但成员函数已被证明是一个问题。
我已经用布莱恩的建议更新了我的问题。请注意,多重继承会导致应该调用哪个函数的歧义 - 一个来自CRTP<DerivedDerived<T>>
或来自Derived<T>
的函数:
template<typename T>
struct DerivedDerived : public Derived<T>, public CRTP<DerivedDerived<T>> {};
您需要一个派生自 Derived 的 CRTP 才能由 DerivedDerived 使用
template<typename T>
struct CRTP
{
template<typename TypeRHS>
T& operator+=(const TypeRHS& rhs)
{
// do something
return static_cast<T&>(*this);
}
};
template<typename T>
struct Derived : public CRTP<Derived<T>> {
};
template<typename T>
struct CRTPForDerived : public Derived<T>
{
template<typename TypeRHS>
T& operator+=(const TypeRHS& rhs)
{
// do something
return static_cast<T&>(*this);
}
};
template<typename T>
struct DerivedDerived : public CRTPForDerived<DerivedDerived<T> >
{};
对于算术运算符的特定情况,您可以通过在类/结构之外声明运算符来解决此问题。在这种情况下,不需要 CRTP 构造:
#include <type_traits>
// Replaces template<typename> struct CRTP;
struct MyOperatorsBase {
};
template<typename T>
struct Derived : public MyOperatorsBase {
};
template<typename T>
struct DerivedDerived : public Derived<T> {
};
// Overload "a += b" defined only if "a" derives from MyOperatorsBase.
template<typename RetType, typename RhsType>
std::enable_if_t<std::is_base_of_v<MyOperatorsBase,RetType>,RetType&> operator +=(RetType& lhs, const RhsType& rhs) {
// do something.
return lhs; // no downcasting static_cast needed, which is nice
}
现场演示
对于未来的读者,我能想到的最通用和模块化的解决方案实际上是将我需要在DerivedDerived
继承的相关部分从Derived
分离到它们的单独类中,然后Derived
可以继承这些以及 CRTP 类,然后可以做同样的事情来DerivedDerived
有效地将两者放在层次结构中的同一级别。
相关文章:
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针