Почему нельзя передавать лямбду как аргумент шаблона?
#include <iostream>

template <class Body>
void call(const Body& body) {
    body();
};

void test() {
  std::cout << "function" << std::endl;
}

int main() {
  call(test);
  call([]() {
    std::cout << "lambda" << std::endl;
  });
  return 0;
}
Дело в том, что лямбда — это объект неизвестного класса с операцией (). И только так её вызывают.
Ну, например то, что у неё тип не совпадает с тем, что указано в шаблоне. У неё тип что-то вроде класса с оператором (). Но даже если вы так напишите, то всё равно работать не будет. Ведь нужен ещё и объект для вызова метода.