Метод класса, принимающий лямбда-выражения, представляющие функции различного числа аргументов
Я хотел бы передать функции в метод универсального класса, чтобы универсальный класс мог вызывать функции, не требующие аргументов, одного аргумента, двух аргументов и т. Д.
Я видел различные шаблоны, но мне не нравится синтаксис. Предыдущий вопрос SO рекомендовал передавать лямбда-выражения, оборачивая функцию:
где ответ:
void run_callback(std::function<void()>& func)
{
func();
}
run_callback([]{ func_without_params(); });
и поэтому я добавил метод, который не требует аргументов:
void func_without_params()
{
std::cout << "x" << std::endl;
}
но когда я звоню:
run_callback([]{ func_without_params(); });
в VS2013 intellisense обнаруживает ошибку, и я получаю ошибку компилятора:
error C2664: 'void run_callback(std::function<void (void)> &)' :
cannot convert argument 1 from
'main::<lambda_de925f4d5cd926a8bb664f9c057a7a19>' to
'std::function<void (void)> &'
Что такое main::<lambda_de925f4d5cd926a8bb664f9c057a7a19>
тип? Я не до конца понимаю ошибку.
2 ответа
За исключением злых расширений компилятора, вы не можете инициализировать неконстантную ссылку (параметр func
) с чем-то, что не является l-значением. Сделайте параметр const:
#include <functional>
#include <iostream>
void run_callback(std::function<void()> const &func)
{
func();
}
void func_without_params()
{
std::cout << "x" << std::endl;
}
int main()
{
run_callback([] { func_without_params(); });
}
Что такое
main::<lambda_de925f4d5cd926a8bb664f9c057a7a19>
тип?
Что ссылки говорят о лямбда-выражении:
Лямбда-выражение является выражением prvalue уникального неименованного неагрегированного неагрегированного типа класса, известного как тип закрытия, который объявляется в наименьшей области блока, области класса или области пространства имен, содержащей лямбда-выражение.
безымянный только для программистов, компилятор знает это имя и в вашем случае lambda_de925f4d5cd926a8bb664f9c057a7a19
это имя типа закрытия. main
относится к функции, внутри которой был определен тип замыкания.
Вы можете использовать https://cppinsights.io/, чтобы заглянуть за кулисы. cppinsights использует Clang, который не принимает привязку Rvalue к ссылке Lvalue, поэтому измените код на:
void run_callback(std::function<void()> func) // take by value
и вывод из cppinsights:
int main() { // scope of closure type
class __lambda_14_16 { // closure type
public: inline /*constexpr */ void operator()() const
{
func_without_params();
}
};
run_callback(std::function<void ()>(__lambda_14_16{}));
}