【发布时间】:2018-04-01 17:07:32
【问题描述】:
我有以下类层次结构:
template<typename T>
class GridMetric{
virtual GridMetric* getNeighbors(T value) = 0;
};
template<size_t N, typename T, typename Derived>
class MatrixBase : public GridMetric<T>{
virtual MatrixBase<N,T,Derived>* getNeighbors(T value){return nullptr;}
};
template<size_t N, typename T>
class MatrixND : public MatrixBase<N,T,MatrixND<N,T>>{
virtual MatrixND<2,T>* getNeighbors(T value){ /* ... */}
};
template<typename T>
class MatrixND<2,T> : public MatrixBase<2,T,MatrixND<2,T>>{
virtual MatrixND<2,T>* getNeighbors(T value){ /* ... */}
};
template<typename T>
class Vector : public GridMetric<T>{
virtual MatrixND<2,T>* getNeighbors(T value){ /* ... */}
};
所以我的抽象类GridMetric有两个派生类,Vector和MatrixBase。我的 Matrix 基类具有 crtp 样式派生类 MatrixND,并且有一个 N=2 的 MatrixND 特化。
每个类都应该有一个虚函数 getNeighbors 来返回一个 MatrixND 指针。
一切正常,除了 MatrixND 类抱怨 MatrixND 是无效的协变返回类型:
error: invalid covariant return type for ‘MatrixND<2ul, T>* MatrixND<N, T>::getNeighbors(T&) [with long unsigned int N = 3ul; T = double]’
virtual MatrixND<2,T>* getNeighbors(T& in){
我的第一个问题是为什么以及如何处理它?由于 MatrixND 继承自 MatrixBase!
我的第二个问题:这是不好的设计,因为我总是会返回原始指针?我读了很多表达式 return new obj..,但也认为这显然是糟糕的设计。是否有其他可能实现相同的目标?
编辑:所以,过了一段时间,我意识到原来的计划行不通,我通过模板类找到了一个更简单的解决方案,我想在其中使用那些类。
无论如何,问题是,为什么专门的 MatrixND 类不能是通用 MatrixND 类中的协变返回类型。我没有找到任何说它是不允许的。
【问题讨论】:
-
错字?
Vector中的返回类型是MatrixND<2,T>*?并且MatrixND<2,T>中有一个N,应该是2。 -
是的,N 是个错误。是的,计划是返回一个指向二维矩阵的指针。
-
那么你应该在
Vector之前声明MatrixND。 -
你说得对,我把它放在最后,但这对我的代码没有任何影响。我转发声明所有类以排除此类错误。
-
一般的
MatrixND<N, T>应该返回MatrixND<N, T> *,而不是MatrixND<2, T> *。
标签: c++ inheritance covariance crtp