Collections of generic traits

Say I have the following:

trait A {}
trait B {}
trait C<T: A, W: B> {}

Would it be possible to do something like this?

Vec<&C<A, B>> 

i.e. a Vec that stores trait objects for the generic trait C for with different implementations of A and B?

Sort of. The way that's written, some concrete CImpl type could implement C<W, X> and C<Y, Z> so you can't just have a blanket:

// implement `C<A, B>` for any type implementing `C<SizedA, SizedB>`
impl<T: A, W: B, CImpl> C<A, B> for CImpl where CImpl: C<T, W> {}

However, you can choose which C<T: A, W: B> implementation is used by C<A, B>.

trait A {}
trait B {}
// Make sure to allow unsized type parameters
trait C<T: ?Sized + A, W: ?Sized + B> {
    fn foo(&self);
}

struct AImpl;
struct BImpl;
struct CImpl(AImpl, BImpl);

impl A for AImpl {}
impl B for BImpl {}
impl C<AImpl, BImpl> for CImpl {
    fn foo(&self) {}
}

// Choose the implementation of `C`. In this case, we're choosing
// `C<AImpl, BImpl>`.
impl C<A, B> for CImpl {
    fn foo(&self) {
        <Self as C<AImpl, BImpl>>::foo(self);
    }
}

fn main() {
    let c = CImpl(AImpl, BImpl);
    let mut v: Vec<&C<A, B>> = Vec::new();
    v.push(&c as &C<A, B>);
}
2 Likes