Hauleth
Hauleth

Reputation: 23566

Operator for parametrized struct is dependant on another operator

I'm writing LoG filter in Rust and I wanted to use | as operator for element wide multiplication operator (a_{i,j} * b_{i,j}), but compilator is complaining about Output result. It say that self[(i, j)] * out[(i, j)] does not equal Mul<N>::Output.

impl<N> BitOr<Matrix<N>> for Matrix<N> where N: Mul<N> {
    type Output = Matrix<N>;

    fn bitor(self, other: Matrix<N>) -> Matrix<N> {
        if self.width() != other.width() ||
            self.height() != other.height() {
                panic!("Matrices need to have equal dimensions");
            }

        let mut out = Matrix::new(self.width(), self.height());

        for i in 0..(self.width()) {
            for j in 0..(self.height()) {
                out[(i, j)] = self[(i, j)] * out[(i, j)];
            }
        }

        out
    }
}

Is there any way to set output based on Mul<N>::Output type?

Upvotes: 0

Views: 55

Answers (2)

Shepmaster
Shepmaster

Reputation: 430841

You didn't provide a small runnable example, so I made my own. This works:

use std::ops::{Mul,BitOr};

#[derive(Copy,Show)]
struct Matrix<N>(N, N);

impl<N> BitOr<Matrix<N>> for Matrix<N> where N: Mul<N, Output=N> {
    type Output = Matrix<N>;

    fn bitor(self, other: Matrix<N>) -> Matrix<N> {
        Matrix(self.0 * other.0, self.1 * other.1)
    }
}

fn main() {
    let a = Matrix(-1,-1);
    let b = Matrix(2,3);
    let c = a | b;

    println!("{:?}", c)
}

The main thing I had to do was N: Mul<N, Output=N>, which specifies that N must be multipliable by another N and will result in another N.

Upvotes: 1

Vladimir Matveev
Vladimir Matveev

Reputation: 127801

I guess this should work:

impl<N> BitOr<Matrix<N>> for Matrix<N> where N: Mul<N> {
    type Output = Matrix<<N as Mul<N>>::Output>;

    fn bitor(self, other: Matrix<N>) -> Matrix<<N as Mul<N>>::Output> {
        if self.width() != other.width() ||
            self.height() != other.height() {
                panic!("Matrices need to have equal dimensions");
            }

        let mut out = Matrix::new(self.width(), self.height());

        for i in 0..(self.width()) {
            for j in 0..(self.height()) {
                out[(i, j)] = self[(i, j)] * out[(i, j)];
            }
        }

        out
    }
}

Upvotes: 3

Related Questions