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

C++ 如何从C+;内部访问局部变量+;11匿名函数?,c++,lambda,c++11,scope,anonymous-function,C++,Lambda,C++11,Scope,Anonymous Function,我正在对向量(权重)进行简单的规范化,试图利用STL算法使代码尽可能干净(我意识到这对于for循环来说非常简单): 目前,tot对匿名函数不可见,因此无法编译。使局部变量对匿名函数可见的最佳方法是什么?您需要一个闭包 float tot = std::accumulate(weights.begin(), weights.end(), 0); std::transform(weights.begin(), weights.end(), [tot](float x)->float{retur

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

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

您需要一个闭包

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

  • [x]
  • 参考
    [&x]
  • 通过引用当前在范围内的任何变量
    [&]
  • 与3相同,但按值
    [=]

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

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

    或者,您可以使用捕获默认值隐式捕获
    tot

    float tot = std::accumulate(weights.begin(), weights.end(), 0);
    std::transform(weights.begin(), weights.end(), [=](float x)->float{return(x/tot);});
    
    lambda可以从环境范围“捕获”变量:

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

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

    太棒了!关于STL中C++11匿名函数的使用,有没有很好的web/book参考资料?我在网上发现的很多东西要么是针对匿名函数的过时解决方法,要么是随机的博客帖子。@bd1 C++0x上的维基百科实际上相当不错。此外,公众可获得的最后一份标准草案称为n3424。不幸的是,目前还没有关于C++0x的书籍。如果您使用
    [=]
    创建一个闭包,并且它复制了封闭范围内的所有变量,那么这是否包括全局变量?它什么时候停止向上爬范围阶梯?@Seth I应该更明确:当使用捕获默认值(
    &
    =
    )时,仅捕获lambda主体内实际使用(odr-)的实体。这意味着只有在您访问全局文件时,才会制作全局文件的副本。捕捉默认值见§5.1.2.11,范围规则见§5.1.2.9。对不起,0应该是0.0!editedWhat如果我将lambda解析为函数参数。它抛出一个错误,指出lambda函数不是参数的正确类型。@注意:由于不能说出lambda表达式的类型,因此很难让参数为闭包类型的函数。通常,如果需要管理异构的可调用集合,可以使用函数模板推断类型,或者使用类型擦除包装器,例如
    std::function
    float tot = std::accumulate(weights.begin(), weights.end(), 0);
    std::transform(weights.begin(), weights.end(), [=](float x)->float{return(x/tot);});
    
    [ ..., N, ... ](int a, int b) -> int  { return (a + b) * N; }
     ^^^^^^^^^^^^^  ^^^^^^^^^^^^     ^^^^
     captured vars  local params     ret.type