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

发布于 2024-11-29 22:02:54 字数 298 浏览 1 评论 0原文

我正在对向量(权重)进行简单的归一化,尝试利用 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 对匿名函数,因此无法编译。使局部变量对匿名函数可见的最佳方法是什么?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

可爱暴击 2024-12-06 22:02:54

你需要一个关闭。

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 lambda 支持通过以下方式捕获:

  1. [x]
  2. 引用 [&x]
  3. 通过引用 [&] 当前作用域中的任何变量>
  4. 与 3 相同,但按值 [=]

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

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].

山有枢 2024-12-06 22:02:54

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

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

您可以按值或按引用捕获,并且可以使用特殊语法 [=][&]从环境范围捕获任何东西,即你实际最终使用的任何东西。

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.

仅此而已 2024-12-06 22:02:54

您需要将 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);});

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);});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文