2

After reading this, I'll have a similar question about overloading math operators.

Considering this code basis, which assumes that T objects can be added by value and gives a O:

use std::ops::Add;

struct NoCopy<T>(T);

impl<T: Add<Output = O>, O> Add for NoCopy<T> {
    type Output = NoCopy<O>;

    fn add(self, other: Self) -> Self::Output {
        NoCopy(self.0 + other.0)
    }
}

fn main() {
    let a = NoCopy::<isize>(5);
    let b = NoCopy::<isize>(3);

    let _c = a + b;
}

I would like to provide with one implementation of the Add trait to work on &NoCopy<T> and provide a NoCopy<O> instance, making the assumption that Add operator is provided for &T (and gives a O). T would not require to respect the Copy trait.

But I can't figure out how to write it, especially the generics bindings.

impl<???> Add for &NoCopy<T> {
    type Output = NoCopy<O>;

    fn add(self, other: Self) -> Self::Output {
        NoCopy(&self.0 + &other.0)
    }
}

What the missing part (???) would look like?

Guillaume LemaƮtre
  • 1,230
  • 13
  • 18

1 Answers1

2

You can put a lifetime constraint on &T:

impl<'a, T: 'a, O> Add for &'a NoCopy<T>
where
    &'a T: Add<Output = O>,
{
    type Output = NoCopy<O>;

    fn add(self, other: Self) -> Self::Output {
        NoCopy(&self.0 + &other.0)
    }
}

(playground)

L. F.
  • 19,445
  • 8
  • 48
  • 82