web-dev-qa-db-fra.com

c ++ 0x: bonne façon de recevoir un lambda comme paramètre par référence

Quelle est la bonne façon de définir une fonction qui reçoit un int->int paramètre lambda par référence?

void f(std::function< int(int) >& lambda);

ou

void f(auto& lambda);

Je ne suis pas sûr que la dernière forme soit même une syntaxe légale.

Existe-t-il d'autres façons de définir un paramètre lambda?

66
lurscher

Vous ne pouvez pas avoir de paramètre auto. Vous avez essentiellement deux options:

Option n ° 1: utilisez std::function comme vous l'avez montré.

Option n ° 2: utilisez un paramètre de modèle:

template<typename F>
void f(F &lambda) { /* ... */}

L'option n ° 2 peut, dans certains cas, être plus efficace, car elle peut éviter une allocation potentielle de tas pour l'objet fonction lambda incorporé, mais n'est possible que si f peut être placé dans un en-tête en tant que fonction modèle. Il peut également augmenter les temps de compilation et l'empreinte I-cache, comme tout modèle. Notez qu'il peut également n'avoir aucun effet, car si l'objet fonction lambda est suffisamment petit, il peut être représenté en ligne dans le std::function objet.

72
bdonlan

J'utiliserais template comme:

template<typename Functor>
void f(Functor functor)
{
   cout << functor(10) << endl;
}

int g(int x)
{
    return x * x;
}
int main() 
{
    auto lambda = [] (int x) { cout << x * 50 << endl; return x * 100; };
    f(lambda); //pass lambda
    f(g);      //pass function 
}

Sortie:

500
1000
100

Démo: http://www.ideone.com/EayVq

33
Nawaz

Je sais que ça fait 7 ans, mais voici un moyen que personne d'autre n'a mentionné:

void foo(void (*f)(int)){
    std::cout<<"foo"<<std::endl;
    f(1); // calls lambda which takes an int and returns void
}
int main(){
    foo([](int a){std::cout<<"lambda "<<a<<std::endl;});
}

Quelles sorties:

foo
lambda 1

Pas besoin de modèles ou de fonction std ::

2
Puddle