Захват переменной из лямбда-захвата дает ошибку? - PullRequest
2 голосов
/ 10 марта 2012

Следующий код в 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 ) );
    });
  });
}

выдает ошибку

ошибка C3480: «пространство анонимных имен :::: move»: лямбда переменная захвата должна быть из области действия функции

Но я захватил «ходы» по ссылке во внешней лямбде.

Изменение кода для назначения перемещений на временное и захват временного исправляет ошибку. Это не дает ошибки в 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? Или это просто ошибочная функция?

1 Ответ

2 голосов
/ 10 марта 2012

Это известная ошибка , которая, кажется, была исправлена, хотя и слишком поздно для бета-версии VS11, так как ошибка все еще присутствует там.

Другой простой обходной путь - просто неявно захватить переменную во внутренней лямбде:

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 ) );
    });
  });
}

ИМХО, вам, как правило, следует просто неявно фиксировать свои материалы по ссылке, поскольку я не вижу причин делать иначе здесь.

Кстати, благодаря вам я обнаружил другую ошибку , которая может быть связана. Пожалуйста, проголосуйте, если можете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...