Подтвердить что ты не робот

Может ли lambda выражение быть передано как указатель функции?

Я пытаюсь передать лямбда-выражение функции, которая принимает указатель на функцию, возможно ли это?

Вот пример кода, я использую VS2010:

#include <iostream>
using namespace std;

void func(int i){cout << "I'V BEEN CALLED: " << i <<endl;}

void fptrfunc(void (*fptr)(int i), int j){fptr(j);}

int main(){
    fptrfunc(func,10); //this is ok
    fptrfunc([](int i){cout << "LAMBDA CALL " << i << endl; }, 20); //DOES NOT COMPILE
    return 0;
}
4b9b3361

Ответ 1

В версии VC10 RTM нет - но после того, как функция лямбда в VC10 была завершена, стандартный комитет добавил язык, который позволяет безграмотным лямбдам деградировать до указателей функций. Поэтому в будущем это будет возможно.

Ответ 2

Вы можете использовать std::function для этого:

void fptrfunc(std::function<void (int)> fun, int j)
{
    fun(j);
}

Или пойти полностью родовым:

template <typename Fun>
void fptrfunc(Fun fun, int j)
{
    fun(j);
}

Ответ 3

Это работает в VS2010:

template<class FunctorT>
void* getcodeptr(const FunctorT& f) {
  auto ptr = &FunctorT::operator();
  return *(void**)&ptr;
} 

void main() {
  auto hello = [](char* name){ printf("hello %s\n", name); };
  void(*pfn)(char*) = (void(*)(char*)) getcodeptr(hello);
  pfn("world");
}

Ответ 4

Нет. Это не может. По крайней мере, не стоит. Я знаю, что VS2010 реализует их как объектные функторы. Основываясь на том, как они работают, это может быть требование a priori.

Ответ 5

Пока лямбда не использует предложение захвата (т.е. не захватывает переменные сверху), его можно использовать как указатель функции. Компилятор VC внутренне генерирует анонимные функции с различным соглашением о вызовах, поэтому его можно использовать без проблем.