【问题标题】:Why do I get a conflicting implementations error when specializing a trait?为什么在特化特征时会出现冲突的实现错误?
【发布时间】:2017-08-25 20:44:19
【问题描述】:

我不确定我是否理解为什么这段代码无法编译。似乎新的“向量”Mul 特化比默认特化更具体,我不认为我依赖的 Vectorizable 特征没有被定义为在我的箱子外部输入。

#![feature(cfg_target_feature)]
#![feature(specialization)]

use std::marker::PhantomData;
use std::ops::{Mul, Add};

type Dimension = (usize, usize);
type Coordinate = (usize, usize);

pub trait Ordering {
    // omitted
}

pub struct RowMajor {}
impl Ordering for RowMajor {}

pub struct ColumnMajor {}
impl Ordering for ColumnMajor {}

// NxM matrix
pub struct Matrix<T, O: Ordering> {
    dim: Dimension,
    values: Vec<T>,

    // needed so that we can add type bound to struct
    ordering: PhantomData<O>,
}

trait VectorSize {}

struct V4x {}
impl VectorSize for V4x {}
// others defined for other sizes

trait Vectorizable {
    type SimdType; /*: simd::Simd */
    type VectorSize: VectorSize;
}

#[cfg(target_feature = "sse")]
impl Vectorizable for f32 {
    type SimdType = f32; /* simd::f32x4 */
    type VectorSize = V4x;
}

impl<'a, 'b, T1, T2, O1: Ordering, O2: Ordering>
    Mul<&'b Matrix<T2, O2>> for &'a Matrix<T1, O1>
where
    T1: Mul<T2> + Clone,
    T2: Clone,
    <T1 as Mul<T2>>::Output: Add<Output = <T1 as Mul<T2>>::Output> + Clone + Default,
{
// always output row major because we compute in row major order
    type Output = Matrix<
        <T1 as Mul<T2>>::Output
        , RowMajor>;

// self is a &'a
    default fn mul(self, rhs: &'b Matrix<T2, O2>) -> Self::Output
    {
        unimplemented!();
    }
}

impl<'a, 'b, T: Vectorizable> Mul<&'b Matrix<T, ColumnMajor>> for &'a Matrix<T, RowMajor> {
    fn mul(self, rhs: &'b Matrix<T, ColumnMajor>) -> Self::Output {
        unimplemented!();
    }
}

(playground)

error[E0119]: conflicting implementations of trait `std::ops::Mul<&Matrix<_, ColumnMajor>>` for type `&Matrix<_, RowMajor>`:
  --> src/main.rs:65:1
   |
46 | / impl<'a, 'b, T1, T2, O1: Ordering, O2: Ordering>
47 | |     Mul<&'b Matrix<T2, O2>> for &'a Matrix<T1, O1>
48 | | where
49 | |     T1: Mul<T2> + Clone,
...  |
62 | |     }
63 | | }
   | |_- first implementation here
64 | 
65 | / impl<'a, 'b, T: Vectorizable> Mul<&'b Matrix<T, ColumnMajor>> for &'a Matrix<T, RowMajor> {
66 | |     fn mul(self, rhs: &'b Matrix<T, ColumnMajor>) -> Self::Output {
67 | |         unimplemented!();
68 | |     }
69 | | }
   | |_^ conflicting implementation for `&Matrix<_, RowMajor>`

【问题讨论】:

    标签: rust


    【解决方案1】:

    Vectorizable 实现更具体,例如它没有提及任何关于T * T 是通用操作所要求的有效操作。

    您需要为Vectorizable impl 添加更多边界以匹配通用边界:

    impl<'a, 'b, T> Mul<&'b Matrix<T, ColumnMajor>> for &'a Matrix<T, RowMajor> 
    where
        T: Vectorizable + Mul + Clone,
        T::Output: Add<Output = T::Output> + Clone + Default,
    {
    

    或者,您可以将这些边界添加为Vectorizable 的超特征:

    trait Vectorizable: Mul<Output=Self> + Add<Output = Self> + Clone + Default {
        // ...
    }
    
    impl<'a, 'b, T: Vectorizable> Mul<&'b Matrix<T, ColumnMajor>> for &'a Matrix<T, RowMajor> {
        // ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-24
      • 2022-11-02
      相关资源
      最近更新 更多