2016-01-04 7 views
1

я могу объявить анонимные функции (они такие же, как лямбда, но без «контекста» - [...]) без auto легко:Как объявить лямбду с указателями функций (без авто)?

#include <iostream> 

using namespace ::std; 

void foo(void (*f)(char)) 
{ 
    f('r'); 
} 

int main() 
{ 
    void (*anon)(char) = [](char c) -> void { cout << c << endl; }; 
    foo(anon); 
    return 0; 
} 

Но как объявить лямбда? Это единственный возможный способ? (возможно, с typedef). Здесь я использую ::std::function, но я не упомянул контекст е где в качестве аргументов Foo ...:

#include <iostream> 
#include <functional> 

using namespace ::std; 

//int foo(auto f, char x) // !only since c++14 
int foo(function<int(char)> f, char x) 
{ 
    return f(x+1); 
} 

int main() 
{ 
    int a = 5, b = 10; 

    //void (*lambda)(char) = [](char c) { cout << c << endl; }; 
    //auto sample_lambda = [&a,b](char c) -> int // !only since c++11 
    function<int(char)> sample_lambda = [&a,b](char c) -> int 
     { 
      for (;a<b;a++) 
       cout << a << c << endl; 
      return (int)c+a; 
     }; 

    foo(sample_lambda, 's'); 
    return 0; 
} 
+0

определить foo как функцию шаблона. 'template void foo (Функция && f) {f ('r'); } ' –

+1

« Объявление лямбды »не имеет смысла. Лямбда - это тип * выражения *, и вы не можете делиться выражениями, не более, чем можете, скажем, «объявить сумму» или «объявить вызов функции». –

+2

Не захватывающее выражение лямбда может распадаться на указатель на функцию, но это * не * указатель на функцию. –

ответ

5

Вы не можете.

Тип закрытия - уникальный, неназванный тип. Ваш первый пример работает, потому что типы закрытия имеют функцию преобразования к указателю на функцию, если они ничего не захватывают, а не потому, что закрытие равно a void (*) (char).

Вы должны просто придерживаться auto, так как std::function может иметь дополнительные накладные расходы для стирания типа.

0

auto как параметр является расширением, предоставляемым GCC и другими. Вместо этого вы можете использовать шаблоны:

template<typename T> 
int callFoo(T funct, int x) { 
    return funct(x+1); 
}