我的矩阵实现
pub struct Matrix<const M: usize, const N: usize, T: Num + Neg + Copy>(Box<[[T; N]; M]>);
impl<const M: usize, const N: usize, T: Num + Neg + Copy> Index<(usize, usize)> for Matrix<{M}, {N}, T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &Self::Output {
&self.0[index.0][index.1]
}
}
由矩阵定义列向量和行向量
type CVector<const N: usize, T> = Matrix<{1}, {N}, T>;
type RVector<const N: usize, T> = Matrix<{N}, {1}, T>;
impl<const N: usize, T: Num + Neg + Copy> Index<usize> for CVector<{N}, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self[(0,index)]
}
}
impl<const N: usize, T: Num + Neg + Copy> Index<usize> for RVector<{N}, T> {
type Output = T;
fn index(&self, index: usize) -> &Self::Output {
&self[(index,0)]
}
}
错误
error[E0119]: conflicting implementations of trait `Index<usize>` for type `matrix::Matrix<1, 1, _>`
--> src/vector.rs:38:1
|
30 | impl<const N: usize, T: Num + Neg + Copy> Index<usize> for CVector<{N}, T> {
| -------------------------------------------------------------------------- first implementation here
...
38 | impl<const N: usize, T: Num + Neg + Copy> Index<usize> for RVector<{N}, T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `matrix::Matrix<1, 1, _>`
我知道模板专业化现在还不稳定。有什么技巧可以解决这个问题吗?
我尝试了模板专业化。
1条答案
按热度按时间wnvonmuf1#
即使有了专门化,由于冲突,这些实现也是不可能的。不要忘记类型别名仍然与底层类型完全相同,因此
impl<...> Index<usize> for CVector<N, T>
与impl<...> Index<usize> for Matrix<{1}, N, T>
完全相同。因此您有以下两种实现:在
N == 1
的情况下,这里有一个冲突:Index<usize> for Matrix<{1}, {1}, T>
的两种实现,并且出于专门化的目的,两者都没有明显地比另一个更“具体”。我的建议是为
RVector
和CVector
使用新类型:然后,您可以在这些上使用
impl Deref
来轻松访问底层矩阵,同时仍然提供专门的向量特定功能,如您的Index
实现。使用repr(transparent)
,您甚至可以添加unsafe
访问器,直接从&Matrix<{1}, N, T>
转换为&CVector<N, T>
,而无需额外复制。最后,我还建议您使用类似于我在
gridly
(我的2D网格库)中使用的模式。有很多功能在行和列上重复,因此我使用Row
和Column
类型而不是usize
进行索引,并使用traitComponent
对它们进行泛化。例如,Grid::single_view
可以获取单行或单列的视图(通过调用grid.single_view(Row(2))
或grid.single_view(Column(4))
)。