我目前正在尝试为 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,因为它至少可以工作,但如果有人能指出我忽略了哪些愚蠢的地方,我将不胜感激。
最佳答案
问题在于
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);
});
关于c++ - 使用非捕获 lambda 作为可变参数模板函数的函数指针参数给出 "no matching function call",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56167838/