1

I'm trying to push items into a VecDeque, but I can't get my head around this bit. The compiler complains that my push_back method in the InnerQueue impl is a generic T type (well, it is). How can I fix the code so I can push UserItems into a User typed Queue?

use std::collections::VecDeque;

fn main() {}

struct Queue<T: InnerQueue> {
    name: String,
    queue: T,
}

impl<T: InnerQueue> Queue<T> {
    pub fn new(name: String) -> Queue<T> {
        Queue {
            name,
            queue: T::new(),
        }
    }

    pub fn push<R>(&self, data: R)
    where
        R: QueueItem,
    {
        self.queue.push_back(data);
    }
}

trait QueueItem {}

type UserItem = (u32, u64, u64);

impl QueueItem for UserItem {}

trait InnerQueue {
    fn new() -> Self;
    fn push_back<T: QueueItem>(&mut self, data: T);
}

type User = VecDeque<UserItem>;

impl InnerQueue for User {
    fn new() -> Self {
        VecDeque::new()
    }

    fn push_back<T: QueueItem>(&mut self, data: T) {
        self.push_back(data);
    }
}

Playground

error[E0308]: mismatched types
  --> src/main.rs:46:24
   |
45 |     fn push_back<T: QueueItem>(&mut self, data: T) {
   |                  - this type parameter
46 |         self.push_back(data);
   |                        ^^^^ expected tuple, found type parameter `T`
   |
   = note:       expected tuple `(u32, u64, u64)`
           found type parameter `T`
   = help: type parameters must be constrained to match other types
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Andrew
  • 2,063
  • 3
  • 24
  • 40
  • 1
    You can probably use an associated type and do away with the `QueueItem` trait: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=ebe418ae8b813b955bfae09c1717cac3 – Sven Marnach Mar 23 '20 at 16:51
  • (Haven't thought about this properly, so not posting this as answer.) – Sven Marnach Mar 23 '20 at 16:51
  • 1
    Generally, it would help to think what would happen in your implementation of `push_back` was called multiple times for distinct `T` types. But more specifically, [this question](https://stackoverflow.com/q/53085270/1233251) shows a very similar problem. – E_net4 Mar 23 '20 at 16:53
  • It looks like your question might be answered by the answers of [How do I create a heterogeneous collection of objects?](https://stackoverflow.com/q/27957103/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Mar 23 '20 at 16:54
  • @SvenMarnach Thanks, this seems to be working. I have to read about that `type Item` thing. @Shepmaster Thanks for the link, it explains it well! – Andrew Mar 23 '20 at 17:08
  • 1
    Does this answer your question? [How do I create a heterogeneous collection of objects?](https://stackoverflow.com/questions/27957103/how-do-i-create-a-heterogeneous-collection-of-objects) – trent Mar 23 '20 at 17:21
  • @trentcl It looks like the OP isn't looking for a heterogeneous collection, but that's not really clear from the question. – Sven Marnach Mar 23 '20 at 18:12

0 Answers0