如何从C ++ 11匿名函数中访问局部变量?

时间:2011-08-17 23:53:42

标签: c++ lambda c++11 scope anonymous-function

我正在对向量(权重)进行简单的规范化,试图利用STL算法使代码尽可能干净(我意识到这对于for循环来说非常简单):

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

目前,匿名函数看不到tot,因此无法编译。使局部变量对匿名函数可见的最佳方法是什么?

3 个答案:

答案 0 :(得分:46)

你需要关闭。

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

在这种情况下,tot按值捕获。 C ++ 11 lambdas支持捕获:

  1. value [x]
  2. 参考[&x]
  3. 目前在参考范围[&]
  4. 范围内的任何变量
  5. 与3相同,但按值[=]
  6. 您可以在逗号分隔列表[x, &y]中混合使用上述任何内容。

答案 1 :(得分:8)

lambda可以从环境范围“捕获”变量:

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

您可以按值或按引用进行捕获,您可以使用特殊语法[=][&]从环境范围捕获任何,即实际结束的任何内容使用。

答案 2 :(得分:2)

您需要将tot添加到“捕获列表”中:

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

或者,您可以使用capture-default隐式捕获tot

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