How can I access local variables from inside a C++11 anonymous function?

核能气质少年 提交于 2020-08-20 20:08:46

问题


I'm doing a simple normalization on a vector (weights), trying to make use of STL algorithms to make the code as clean as possible (I realize this is pretty trivial with for loops):

float tot = std::accumulate(weights.begin(), weights.end(), 0.0);
std::transform(weights.begin(), weights.end(), [](float x)->float{return(x/tot);});

At present, tot is not visible to the anonymous function, so this doesn't compile. What's the best way of making a local variable visible to the anonymous function?


回答1:


You need a closure.

float tot = std::accumulate(weights.begin(), weights.end(), 0);
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);});

In this case tot is captured by value. C++11 lambdas support capturing by:

  1. value [x]
  2. reference [&x]
  3. any variable currently in scope by reference [&]
  4. same as 3, but by value [=]

You can mix any of the above in a comma separated list [x, &y].




回答2:


The lambda can "capture" variables from the ambient scope:

[ ..., N, ... ](int a, int b) -> int  { return (a + b) * N; }
 ^^^^^^^^^^^^^  ^^^^^^^^^^^^     ^^^^
 captured vars  local params     ret.type

You can capture by value or by reference, and you can use the special syntax [=] and [&] to capture anything from the ambient scope, i.e. anything you actually end up using.




回答3:


You need to add tot to the "capture list":

float tot = std::accumulate(weights.begin(), weights.end(), 0);
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);});

Alternatively you can use a capture-default to capture tot implicitly:

float tot = std::accumulate(weights.begin(), weights.end(), 0);
std::transform(weights.begin(), weights.end(), [=](float x)->float{return(x/tot);});


来源:https://stackoverflow.com/questions/7100889/how-can-i-access-local-variables-from-inside-a-c11-anonymous-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!