Hello.
I have a template type A
with a template number P
(see code below).
In my real use-case, the type A is from a library and is very similar to the type in the example code. Even though not an empty struct, the real type struct always have the same size whatever the template variable is.
The type A implements A trait B for any template number P.
There is a struct C that contains a tuple of multiple types A with different template variable P (in the example it is 1 and 2).
My question is: Can I iterate over that tuple and call the method of the trait B
?
First way: Duplicate code for all the tuple elements:
c.tuple.N.hello()
That could be problematic if the tuple size gets large enough, and also it is just code duplication.
In my real use-case, I have larger tuple size.
Second way: I thought I could iterate over the tuple in a straightforward way with a for loop. However, the code doesn't compile and returns an error:
error[E0277]: `(A<1>, A<2>)` is not an iterator
Third way: the best I could find for now.
Store references to each element of the tuple casted to B in a static array.
c.refs = Some([&c.tuple.0 as &dyn B, &c.tuple.1]);
Then use for loop to iterate over the array.
for element in c.refs.unwrap() {
element.hello()
}
It works. However, seems like it is somewhat redundant to create self-references and just wrong to store references to objects to which I already have access to in a tuple.
Also, I couldn't find a way to store the references in a static array without Option type.
So, is there any better way to iterate over the elements of same type A with different template variable P implementing same trait B?
The example code:
struct A<const P: u32>;
trait B {
fn hello(&self);
}
impl<const P: u32> B for A<P> {
fn hello(&self) {
println!("Hello: {}", P);
}
}
struct C<'a> {
tuple: (
A::<1>,
A::<2>
),
refs: Option<[&'a dyn B; 2]>,
}
fn main() {
let mut c = C {
tuple: (
A::<1> {},
A::<2> {},
),
refs: None
};
// First way
c.tuple.0.hello();
c.tuple.1.hello();
// Second way?
// for element in c.tuple {
// element.hello()
// }
// Third way
c.refs = Some([&c.tuple.0 as &dyn B, &c.tuple.1]);
for element in c.refs.unwrap() {
element.hello()
}
}