Implementing trait for a struct

Here is trait and struct:

trait A {}
#[derive(Debug, Clone)]
struct B;
#[derive(Debug, Clone)]
struct C;

impl A for B {}
impl A for C {}

I use it as Box<trait object>:

let b_box: Box<dyn A> = Box::new(B.clone());

For convient, I need to the instance of trait A has method to_box so that I can use:

let b_box = B.to_box();
//this b_box is the same as above one

I tried realize it like this, but that does not work:

trait ToBox {
    type T;
    fn to_box(&self) -> Box<Self::T>;
}

impl<M: A + Clone> ToBox for M {
    type T = dyn A;
    fn to_box(&self) -> Box<Self::T> {
        let res: Box<Self::T> = Box::new((self).clone());
        res
    }
}

[E0277] Error: the size for values of type `(dyn A + 'static)` cannot be known at compilation time
   โ•ญโ”€[command_52:1:1]
   โ”‚
 2 โ”‚     type T = dyn A;
   ยท              โ”€โ”€โ”ฌโ”€โ”€  
   ยท                โ•ฐโ”€โ”€โ”€โ”€ doesn't have a size known at compile-time
   ยท 
   ยท Note: required by this bound in `ToBox::T`
โ”€โ”€โ”€โ•ฏ

What am I doing wrong?

Type parameters and associated types are Sized by default. Add the ?Sized bound to the declaration of the associated type T to make this compile.

Additionally, you'll need a 'static bound on the type parameter M in the impl, because Box<dyn Trait> implicitly means Box<dyn Trait + 'static> unless an explicit lifetime annotation is supplied.

2 Likes

Thanks for the solution.

I change the code to this, it works fine:

trait ToBox {
    type T: ?Sized;
    fn to_box(&self) -> Box<Self::T>;
}

impl<M: A + Clone + 'static> ToBox for M {
    type T = dyn A;
    fn to_box(&self) -> Box<Self::T> {
        let res: Box<Self::T> = Box::new((self).clone());
        res
    }
}

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.