Suppose I have a very simple struct:
pub struct MyStruct<T> {
pub val: T
}
I'd like to implement the Add
trait so I can write expressions such as S1 + S2
, where S1
is an instance of MyStruct::<T1>
, S2
is an instance of MyStruct::<T2>
:
impl<T1: Add<T2>, T2> Add<MyStruct::<T2>> for MyStruct<T1> {
type Output = MyStruct<<T1 as Add<T2>>::Output>;
fn add(self, rhs: MyStruct<T2>) -> Self::Output {
return Self::Output {
val: self.val + rhs.val
}
}
}
There's one problem here: the Add
trait is not implemented between dissimilar types (e.g. f64
and i32
, or even f64
and f32
). I'm unable to implement it myself (Error Code E0117). Because of this I can't add, e.g., a MyStruct::<f64>
and a MyStruct::<i32>
.
I'd like to design the generics such that the types are automatically promoted to a "higher type" (similar to the conversion / promotion rules in the Julia language). However, it's not clear to me how to do this using generics. Writing this by hand is straightforward using, e.g., i32::from(...)
or a as f64
, but this would defeat the purpose of using generics to avoid writing boilerplate by hand.
What would be the most clear and elegant way to define a set of promotion / conversion rules for the generic types in this context?
(Apologies in advance for any errors in the above post--I'm new to Rust and still wrapping my head around many of its concepts)