c++ - 从 lambda 捕获中捕获变量会出错?

标签 c++ lambda

VS2010中的代码如下:

void AddBishopMoves( vector<Move> &moves, uint64_t mask, uint64_t occupied, uint64_t valid )
{
  ForEachBit( mask, [&moves,occupied,valid]( Square from )
  {
    auto toMask = BishopAttacks( from, occupied ) & valid;
    ForEachBit( toMask, [&moves, from]( Square to )
    {
      moves.push_back( Move( from, to ) );
    });
  });
}

报错

error C3480: '`anonymous-namespace'::::moves': a lambda capture variable must be from an enclosing function scope

但我确实通过外部 lambda 中的引用捕获了“移动”。

更改代码以将移动分配给临时对象并捕获临时对象可以解决该错误。这在 VS2010 中没有给出错误:

void AddBishopMoves( vector<Move> &moves, uint64_t mask, uint64_t occupied, uint64_t valid )
{
  ForEachBit( mask, [&moves,occupied,valid]( Square from )
  {
    auto& x = moves;
    auto toMask = BishopAttacks( from, occupied ) & valid;
    ForEachBit( toMask, [&x, from]( Square to )
    {
      x.push_back( Move( from, to ) );
    });
  });
}

问题是为什么?

我是否避免了编译器试图警告我的一些微妙的逻辑错误? 这是 c++11 捕获语义不支持的吗? 或者这只是一个有缺陷的功能?

最佳答案

这是a known bug该问题似乎已得到修复,尽管对于 VS11 Beta 来说为时已晚,因为该错误仍然存​​在。

另一个简单的解决方法是隐式捕获内部 lambda 中的变量:

void AddBishopMoves( vector<Move> &moves, uint64_t mask, uint64_t occupied, uint64_t valid )
{
  ForEachBit( mask, [&moves,occupied,valid]( Square from )
  {
    auto toMask = BishopAttacks( from, occupied ) & valid;
    ForEachBit( toMask, [&, from]( Square to ) // <== implicit capture of 'moves'
    {
      moves.push_back( Move( from, to ) );
    });
  });
}

恕我直言,您通常应该通过引用隐式捕获您的内容,因为我认为这里没有任何理由这样做。

顺便说一句,多亏了你我发现了another bug ,这可能是相关的。如果可以的话请点赞。

关于c++ - 从 lambda 捕获中捕获变量会出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9647764/

相关文章:

python - 如何使用 Pandas groupby 聚合、组合数据帧

python - 如何在for循环中使用lambda?

c# - 按 lambda 表达式动态排序

c++ - Visual C++ 2015 中的 SIGINT 处理程序重置

c++ - 编译时素数检查

c++ - 以下代码是否容易出现内存泄漏?

c++ - Raytracer 纹理贴图留下伪影

c++ - 在 Windows 中加入等效项

c++ - 如何在 C++11 的成员函数中实现多态函数?

c# - 使用对象初始值设定项创建实例的表达式