首页 > 解决方案 > 使用非捕获 lambda 作为可变参数模板函数的函数指针参数给出“没有匹配的函数调用”

问题描述

我目前正在尝试为 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 以接受 lambda

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

现在在 func(...); 处使用 lambda 生成错误“调用不匹配”和使用 foo 生成“函数参数太少”。

我可能正在监督一些事情,但即使在搜索谷歌之后我也找不到什么。

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

标签: c++templateslambdafunction-pointersvariadic-templates

解决方案


问题是,与

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

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

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

T...列表无法再从func.

所以你不能打电话

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

推荐阅读