Reputation: 53
I am currently experimenting with writing a "foreach with" for an ecs.
template <typename... T>
void foreach (void (*func)(Entity e, T... args)){
std::vector<Entity> intersection;
// ... Find all entities with all the types
for (size_t i = 0; i < intersection.size(); i++)
func(intersection[i], *getComp<T>(intersection[i])...);
}
It's working perfectly with a function argument
void foo(Entity e, int i)
{
setComp<int>(e, (int) e);
}
foreach(foo); // Works as expected
But not with the same function copy and pasted as lambda
foreach( // even if foreach<int>
[](Entity e, int i) {
setComp<int>(e, (int) e);
}); // error "no matching function call" "no instance of template matches"
Changing foreach to accept lambdas
template <typename... T, typename F>
void foreach (F func){
std::vector<Entity> intersection;
// ... Find all entities with all the types
for (size_t i = 0; i < intersection.size(); i++)
func(intersection[i], *getComp<T>(intersection[i])...);
}
now produces an error "no match for call to" with lambda and "too few arguments to function" with foo, both at func(...);.
I'm probably overseeing something, but even after scouring google and SO I just can't find what.
I'll probably just gonna use the function pointer variant and give up on passing lambdas as that works at least, but would be very gratefull if somebody could point out what dumb me has overlooked.
Upvotes: 4
Views: 117
Reputation: 66200
The problem is that with
template <typename... T>
void foreach (void (*func)(Entity e, T... args))
the variadic list of types T...
is deduced from func
arguments.
With
template <typename... T, typename F>
void foreach (F func)
the T...
list can't be deduced anymore from func
.
So you can't call
foreach( // even if foreach<int>
[](Entity e, int i) {
setComp<int>(e, (int) e);
});
You have to explicit T...
// ....VVVVV
foreach<int>(
[](Entity e, int i) {
setComp<int>(e, (int) e);
});
Upvotes: 2