Passage par référence constante dans la liste de capture lambda

Je construis une fonction lambda qui nécessite l’access à un nombre non négligeable de variables dans le contexte.

const double defaultAmount = [&]{ /*ToDo*/ }(); 

Je préférerais ne pas utiliser [=] dans la liste, car je ne souhaite pas créer beaucoup de copies de qualité.

Je suis préoccupé par la stabilité du programme si j’utilise [&] car je ne veux pas que le lambda modifie le jeu de capture.

Puis-je passer par référence const? [const &] ne fonctionne pas.

Peut-être qu’un bon compilateur optimise les copies de valeur, alors [=] est préférable.

Vous pouvez créer et capturer des références const explicitement:

 int x = 42; const int& rx = x; auto l = [&rx]() { x = 5; // error: 'x' is not captured rx = 5; // error: assignment of read-only reference 'rx' }; 

La liste de capture est limitée dans ce qui peut être capturé; fondamentalement par valeur ou par référence (nommé ou par défaut), le pointeur this et rien.

De la référence ;

capture-list – liste de zéro ou plusieurs captures séparées par des virgules, commençant éventuellement par capture-default . La liste de capture peut être passée comme suit (voir ci-dessous pour la description détaillée):

  • [a,&b]a est capturé par la valeur et b est capturé par la référence.
  • [this] capture le pointeur this par valeur
  • [&] capture toutes les variables automatiques odr-utilisées dans le corps du lambda par référence
  • [=] capture toutes les variables automatiques odr-utilisées dans le corps du lambda par valeur
  • [] ne capture rien

Vous pouvez créer des const& locaux pour tous les objects que vous souhaitez capturer et utiliser ceux du lambda.

 #include  using namespace std; int main() { int a = 5; const int& refa = a; const int b = [&]() -> int { //refa = 10; // attempts to modify this fail return refa; }(); cout << a << " " << b << endl; } 

La capture peut être soit pour toutes les références, soit une liste explicite de ce qui est requirejs;

 const int b = [&refa]() 

Une autre alternative consiste à ne pas capturer les variables locales du tout. Vous créez ensuite un lambda qui accepte comme arguments les variables dont vous avez besoin. Cela peut prendre plus de temps que le nombre de variables locales augmente, mais vous avez plus de contrôle sur la manière dont le lambda accepte ses arguments et peut utiliser les données.

 auto lambda = [](const int& refa /*, ...*/) { */...*/ } lambda(...); 

Malheureusement, la grammaire C ++ 11 ne le permet pas, donc non.

Vous pouvez capturer une référence constante à un object, pas à un object lui-même:

 A a; const A& ref_a = a; const double defaultAmount = [&]{ ref_a.smth(); }();