How to express a generic From between two math Vectors with different element types?


#1

Say I have a
struct Vec3d< T >
where T:Float+Copy{
x:T, y:T, z:T
}

I want to

impl<T, U> From<Vec3d< U >> for Vec3d< T >
where T:From< U >{
    fn from(rhs:Vec3d< U >) -> Vec3d< T >{
      Vec3d{x:T::from(rhs.x), y:T::from(rhs.y), z:T::from(rhs.z)}
}
}

But the compiler complains there is conflict implementation.

Apparently, if T!=U, the impl should be OK, but From is automatically impled for T, which caused the conflict.

How can I archive my purpose?

It seems that I need a negative bound to ensure that T!=U, but how?

Thanks


#2

Not sure how to get around the From issue, but you can always do something like this:

#[derive(Debug)]
struct Vec3d<T: Copy> {
    x:T,
    y:T,
    z:T
}

impl<T> Vec3d<T> where T:Copy {
    fn copy<U:Into<T>+Copy>(rhs: Vec3d<U>) -> Self {
        Vec3d{ x: rhs.x.into(), y: rhs.y.into(), z: rhs.z.into() }
    }
}

fn main() {
    let a: Vec3d<u16> = Vec3d{x: 1, y: 2, z: 3};
    let b: Vec3d<f64> = Vec3d::copy(a);
    println!("{:?}", b);
}

#3

There’s no way to express negative bounds today. The formulation you’re shooting for can’t be done.

You can define your own trait for such a conversion and then base your generic code on it. Or you can manually impl the conversions you’re interested in for the specific types (a macro can cut down on the boilerplate).


#4

You can’t today; you’ll notice that, for example, Option doesn’t have such a From impl either.

It’s certainly desirable, though, so I suspect new features will show up to allow it eventually.