Reputation: 1978
I'm trying to forward an iterator through a function to give constructing the iterator a more friendly interface.
This was an attempt that didn't quite work
pub fn rep_cartesian_product<'a, T>(iter: T, n: i32)-> itertools::MultiProduct<T>
where T: Iterator + Clone {
(0..n).map(|_| iter).multi_cartesian_product()
}
One of the errors I get is:
"The trait std::clone::Clone
is not implemented for <T as std::iter::Iterator>::Item
". But I'm not sure why this is the case since I put + Clone
in the where clause.
A prior attempt was
pub fn rep_cartesian_product<'a, T>(iter: T, n: i32)-> impl Iterator<Item = Vec<T>>
where T : Iterator {
(0..n).map(|_| iter).multi_cartesian_product()
}
type mismatch resolving <itertools::MultiProduct<T> as std::iter::Iterator>::Item == std::vec::Vec<T>
which is why I tried the previous shared attempt.
Upvotes: 0
Views: 90
Reputation: 155046
You requested that the iterator be Clone
, but you additionally need to request that the items it produces are themselves Clone
with a trait bound like T::Item: Clone
.
Additionally, (0..n).map(|_| iter)
doesn't compile because map()
expects a closure it can call multiple times, and returning iter
makes the closure callable only once. You can fix that by switching to .map(|_| iter.clone())
- or by using std::iter::repeat()
instead.
Here is a version that compiles:
pub fn rep_cartesian_product<T>(iter: T, n: usize) -> itertools::MultiProduct<T>
where
T: Iterator + Clone,
T::Item: Clone,
{
std::iter::repeat(iter).take(n).multi_cartesian_product()
}
Note that you can also return impl Iterator<Item = Vec<T::Item>>
, which has the advantage of hiding the implementation of the iterator.
Upvotes: 3