How to get dereferenced type in metaprogramming

impl<T: Add<Output = T>> Add for &RowMatrix<T> {
    type Output = Result<GetDeReferencedType<Self>>; // GetDeReferencedType<Self> == RowMatrix<T>

I want to get Self type's deferenced type.

e.g. if Self is type T, I want to get the type of Deref::Output if T implement trait Deref

Do you mean something like this?

impl<T> Add for &RowMatrix<T> 
    T: Add<Output = T> + Deref,
    type Output = Result<T::Deref>;

Otherwise, if GetDeReferencedType is meant to be something like Box or Vec where you can "instantiate" it to get Box<Self> or Vec<Self> then this is something called a "higher kinded type" and not currently implemented.

You may be able to get something working using Generic Associated Types.

1 Like

Thanks for your help, I know how to implement that.

To be more concise, this is what I want

impl<T: Add<Output = T>> Add for &RowMatrix<T> {
    type Output = Result<<Self as Deref>::Target>;

That works. Or is it different from what you actually want?

1 Like

Sorry, My poor English makes u all misunderstand.

I just want the deferenced target type of &RowMatrix<T>. I want to implement Add trait for two immutable reference of RowMatrix<T>, so that I can add two matrices by taking the immutable reference &lhs_matrix + &rhs_matrix where lhs_matrix's type and rhs_matrix's type both are RowMatrix<T>. The result of Add op should be type RowMatrix<T>, so I want Add::Output to be type Result<RowMatrix<T>>

The high level abstraction will be:
&RowMatrix<T> + &RowMatrix<T> -> Result<RowMatrix<T>>

Can you modify this example to be what you want, even if it doesn't compile? Or somehow demonstrate how it isn't what you want?

Almost right, but T should not be bounded Copy trait

Here is my implementation:

pub struct RowMatrix<T> {
    rows: usize,
    cols: usize,
    data: Vec<Vec<T>>,

impl<T> Add for &RowMatrix<T>
    for<'a> &'a T: Add<Output = T>,
    type Output = Result<<Self as Deref>::Target>;
    fn add(self, rhs: Self) -> Self::Output {
        if self.rows != rhs.rows || self.cols != rhs.cols {
            return Err(Error::DimensionNotMatched);
        let data = self
            .map(|(lhs, rhs)| {
                    .map(|(le, re)| le + re)

        Ok(RowMatrix {
            rows: self.rows,
            cols: self.cols,

This is the complete code.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.