如何使子类上的操作符返回子类类型?
How can I make operators on subclasses return the subclass type?
我正在将一段代码从一个几何库转换为另一个几何库。在我当前的代码中,我有很多专门化的Point类,我宁愿只有一个模板化的。模板化的新版本有一个重载的加法操作符,定义为;
template<typename To>
Point<T, N> operator+(const Point<To,N>& p) const;
其中T
为包含类型,N
为点的维数。
为了提供旧的用法接口,我必须创建Point类的子类。主要通过混叠一些成员,添加一些函数;
// Old library, could be indexed by var.x, ...
// New library, can only be indexed via. var[i]
int& x = data[0];
int& y = data[1];
int& z = data[2];
// Old library, supplied this function, new one didn't.
void subclass_function();
这就像一个魔咒,这个替换在整个程序的大多数呼叫站点中都发挥了作用。也就是说,除非有算术运算,后跟兼容性类提供的函数,例如:
IntPoint3 index;
// The scalar multiplication results in the Point<int, 3>.
(index * 2).subclass_function();
错误:Point<int, 3>
没有定义subclass_function()
。
建议的解决方案是什么?-(即让操作符返回子类类型)
注1:我宁愿编辑Point类,而不是在每个特化子类中包装所有算术运算符的重载。
注2:特化子类不添加状态
使用奇怪的重复模板模式(CRTP)
template
基类Point_impl
接受其派生类型作为参数。
返回操作符的派生类型。
template<class T, unsigned N, class D>
struct Point_impl {
D* self() { return static_cast<D*>(this); }
D const* self() const { return static_cast<D const*>(this); }
template<typename U, typename D2>
D operator+(Point_impl<U,N,D2> const& o) const {
auto retval = *self();
retval += o;
return retval;
}
};
那么你的派生:
struct Bob:Point_impl<int,3,Bob>{
//...
};
等。
我在self
和is_base_of
中发现static_assert
也是明智的,因为它捕获了一些拼写错误。
相关文章:
- 从父类方法返回子类对象
- 我们可以在没有新实例化的情况下声明一个抽象方法来返回抽象超类中的子类对象吗
- 返回具体子类实例的 C++ 虚拟类函数
- 我如何使子类返回C 中的不那么通用的Typedef
- 当函数返回类型为父类时,如何返回子类的对象?
- 如何使函数返回由子类定义的值?C++
- 提升 Python 包装的虚拟类 - 子类返回错误:与C++签名不匹配
- 将子类返回到基类对象中
- 用返回子类的方法设计C++泛型类
- 为什么编译没有错误?(返回不对所述返回类型进行子类化的类型)
- 返回子类的常量引用
- C++:使用超类和子类,简单计算面积的值返回3.47668e-310,无论我输入什么来计算
- 返回指向子类的指针的好方法
- C++方法返回指向抽象类的指针,需要使用来自子类的方法
- 从超类函数返回子类定义
- 重写QIODevice子类中的readData会返回错误的结果
- 重写子类中的返回类型
- 如何返回“set”方法的子类类型
- 方法返回子类的实例
- 可以对返回子类类型的基类进行赋值操作符吗?