web-dev-qa-db-fra.com

C++ lambda - variable membre de capture

J'ai une classe qui a un pointeur de fonction sur la fonction du noyau, qui peut changer de l'extérieur.

class Bar 
{
   public:
     int i;
}

class Foo 
{
   public:
     std::function<double()> kernel;
     Bar bar;         
};

int main()
{

  Foo f;
  f.kernel = []() -> double { return i * i; }; //this is not working obviously

}

Comment puis-je obtenir un comportement "présenté", par exemple. lire les variables de classe à l'intérieur de lambda. Je peux le contourner en passant f à l'intérieur et en écrivant f.bar.i, mais ce n'est pas une très bonne solution.

13
Martin Perry

En C++ 14, vous pouvez l'écrire en tant que,

f.kernel = [&i = f.bar.i]() -> double { return i * i; };

Si vous n'avez pas C++ 14, vous pouvez également créer une autre variable,

int &i = f.bar.i;
f.kernel = [&i]() -> double { return i*i; };

Bien qu'il n'y ait rien de mal à passer f et à écrire f.bar.i.

19
aslg

Il semble que vous ne pouvez pas le faire . Il n'y a pas de construction pour créer une fonction membre lambda.

Mais vous pouvez probablement suivre la suggestion de @ KerrekSB et, en plus de cette dépêche, appeler toujours pour obtenir la fonction membre:

class Foo 
{
public:
    double kernel()
    {
        _kernel(*this);
    }

    std::function<double(Foo &)> _kernel;
};


Foo f;
f._kernel = [](Foo &f) -> double { return f.i * f.i; };
f.kernel()

Notez que vous ne pouvez pas nommer les deux champs kernel.

7
dhke

La fonction lambda ne connaît pas i ou Bar. Comment pourrait-il savoir? Vous devez passer une référence. Si vous définissez le corps de la fonction différemment afin que vous puissiez passer i en tant que paramètre et que vous l'appelez dans la classe, vous devriez obtenir ce que vous voulez.

0