使用非捕获lambda作为可变参数模板函数的函数指针参数会导致“没有匹配的函数调用”

时间:2019-05-16 11:46:34

标签: c++ templates lambda function-pointers variadic-templates

我目前正在尝试为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的参数太少”使用foo都出现错误。

我可能正在监督某些事情,但是即使在搜寻google和SO之后,我也仍然找不到。

我可能只会使用函数指针变量,并至少放弃传递lambda,因为那至少可行,但是如果有人指出我忽略了什么愚蠢的东西,我将非常感激。

1 个答案:

答案 0 :(得分:2)

问题在于

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