использование не захватывающей лямбда-выражения в качестве аргумента указателя на функцию в шаблоне с переменным числом аргументов дает «не соответствующий вызов функции» - PullRequest
4 голосов
/ 16 мая 2019

В настоящее время я экспериментирую с написанием "foreach with" для 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])...);
}

Он отлично работает с аргументом функции

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

foreach(foo); // Works as expected

Но не с той же копией функции и вставляется как лямбда

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 для принятия лямбда-выражений

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

теперь выдает ошибку «нет совпадения для вызова» с лямбдой и «слишком мало аргументов для работы» с foo, оба в func (...);.

IЯ, вероятно, наблюдаю за чем-то, но даже после того, как отыскиваю Google и SO, я просто не могу найти что.

Я, вероятно, просто буду использовать вариант указателя функции и перестану передавать лямбды, поскольку это работает по крайней мере,но был бы очень признателен, если бы кто-то мог указать, что глупый я упустил из виду.

1 Ответ

2 голосов
/ 16 мая 2019

Проблема в том, что с

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