Is it possible to call a generic function using a concrete type, with a concrete struct?
Here a small example of what I want to do:
trait T {}
trait T2 {}
struct S1 {}
struct S2 {}
impl T for S1 {}
impl T for S2 {}
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
f(bar);
}
fn main() {
test(&S1{}, &S2{}, &|_| println!("called"));
}
I can't get rid of the generic parameter V
because the actual problem I want to solve is much more involved. Furthermore I can't create a wrapping trait, because sometimes I have got a weak signature and sometimes f
requires many more traits.
This is not possible:
fn test<V: T>(foo: &S1, bar: &S2, f: &Fn(&V)) {
f::<S1>(foo);
}
In effect, the function signature says:
f
that takes a trait object of the trait Fn
which takes a reference to a V
V
, so long as it implements the trait T
Then the body of the function says:
f
with the concrete type S1
, regardless of what the caller picked.This cannot work because the V
that the caller picked might not be S1
. In fact, it's most likely not going to be S1
.
About the only suggestion I can offer is to accept another trait object as the argument:
fn test(foo: &S1, bar: &S2, f: &Fn(&T)) {
f(foo);
f(bar);
}
but you've already ruled that out, so...
As a side note, I'm not sure why you are taking the closure as a trait object. Normally, I'd just accept a generic:
fn test<F>(foo: &S1, bar: &S2, f: F)
where F: Fn(&T),
This allows for some level of monomorphization to occur.