使用非捕获 lambda 作为可变参数模板函数的函数指针参数给出 "no matching function call"

using non-capturing lambda as function pointer argument to a variadic template function gives "no matching function call"

我目前正在尝试为 ecs 编写 "foreach with"。

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])...);
}

它与函数参数完美配合

void foo(Entity e, int i)
{
  setComp<int>(e, (int) e);
}

foreach(foo); // Works as expected

但不具有与 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"

更改 foreach 以接受 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])...);
}

现在使用 lambda 产生错误 "no match for call to",使用 foo 产生错误 "too few arguments to function",两者都在 func(...);。

我可能正在监督一些事情,但即使在搜索之后 google 所以我还是找不到什么。

我可能只会使用函数指针变体并放弃传递 lambda,因为它至少可以工作,但如果有人能指出我忽略了什么,我将不胜感激。

问题是

template <typename... T>
void foreach (void (*func)(Entity e, T... args))

类型 T... 的可变参数列表是从 func 个参数推导出来的。

template <typename... T, typename F>
void foreach (F func)

无法再从 func 推导出 T... 列表。

所以你不能打电话

foreach( // even if foreach<int>
    [](Entity e, int i) {
        setComp<int>(e, (int) e);
    }); 

你必须明确 T...

// ....VVVVV
foreach<int>(
    [](Entity e, int i) {
        setComp<int>(e, (int) e);
    });