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

bd1*_*bd1 29 c++ lambda scope anonymous-function c++11

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

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

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

pmr*_*pmr 49

你需要一个关闭.

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

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

  1. [x]
  2. 参考 [&x]
  3. 目前通过引用的范围内的任何变量 [&]
  4. 与3相同,但按价值计算 [=]

您可以在逗号分隔列表中混合上述任何内容[x, &y].

  • @Seth我应该更明确:当使用capture-default(`&`或`=`)时,只捕获lambda体内实际(odr-)使用的实体.这意味着只有在访问全局时才会创建全局副本.有关捕获默认值,请参见§5.1.2.11;有关范围规则,请参见§5.1.2.9. (3认同)

Ker*_* SB 8

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

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

您可以按值或通过引用捕获,并且可以使用特殊语法[=]并从环境范围[&]捕获任何内容,即实际最终使用的任何内容.