web-dev-qa-db-fra.com

Comment déclarer une fonction qui accepte un lambda?

J'ai lu sur Internet de nombreux tutoriels expliquant comment utiliser lambdas avec la bibliothèque standard (comme std::find), et ils étaient tous très intéressants, mais je n'ai trouvé aucun document expliquant comment utiliser un lambda pour mes propres fonctions.

Par exemple:

int main()
{
    int test = 5;
    LambdaTest([&](int a) { test += a; });

    return EXIT_SUCCESS;
}

Comment dois-je déclarer LambdaTest? Quel est le type de son premier argument? Et puis, comment puis-je appeler la fonction anonyme en lui passant - par exemple - "10" comme argument?

75
Thomas Bonini

Étant donné que vous souhaitez probablement également accepter des pointeurs de fonction et des objets de fonction en plus des lambdas, vous souhaiterez probablement utiliser des modèles pour accepter tout argument avec une operator(). C'est ce que font les fonctions std comme find. Cela ressemblerait à ceci:

template<typename Func>
void LambdaTest(Func f) {
    f(10);
}

Notez que cette définition n'utilise aucune fonctionnalité c ++ 0x, elle est donc complètement rétrocompatible. Ce n'est que l'appel à la fonction utilisant des expressions lambda qui est spécifique à c ++ 0x.

69
sepp2k

Si vous ne souhaitez pas tout modéliser, vous pouvez procéder comme suit:

void LambdaTest (const std::function <void (int)>& f)
{
    ...
}
63
doublep

J'aimerais apporter cet exemple simple mais explicite. Il montre comment passer des "objets appelables" (fonctions, objets de fonction et lambdas) à une fonction ou à un objet.

// g++ -std=c++11 thisFile.cpp

#include <iostream>
#include <thread>

using namespace std;

// -----------------------------------------------------------------
class Box {
public:
  function<void(string)> theFunction; 
  bool funValid;

  Box () : funValid (false) { }

  void setFun (function<void(string)> f) {
    theFunction = f;
    funValid = true;
  }

  void callIt () {
    if ( ! funValid ) return;
    theFunction (" hello from Box ");
  }
}; // class

// -----------------------------------------------------------------
class FunClass {
public:
  string msg;
  FunClass (string m) :  msg (m) { }
  void operator() (string s) {
    cout << msg <<  s << endl; 
  }
};

// -----------------------------------------------------------------
void f (string s) {
  cout << s << endl;
} // ()

// -----------------------------------------------------------------
void call_it ( void (*pf) (string) ) {
  pf( "call_it: hello");
} // ()

// -----------------------------------------------------------------
void call_it1 ( function<void(string)> pf ) {
  pf( "call_it1: hello");
} // ()

// -----------------------------------------------------------------
int main() {

  int a = 1234;

  FunClass fc ( " christmas ");

  f("hello");

  call_it ( f );

  call_it1 ( f );

  // conversion ERROR: call_it ( [&] (string s) -> void { cout << s << a << endl; } );

  call_it1 ( [&] (string s) -> void { cout << s << a << endl; } );

  Box ca;

  ca.callIt ();

  ca.setFun (f);

  ca.callIt ();

  ca.setFun ( [&] (string s) -> void { cout << s << a << endl; } );

  ca.callIt ();

  ca.setFun (fc);

  ca.callIt ();

} // ()
7
cibercitizen1