Как я могу сопоставить переменные в лямбда-выражении, которые определены вне лямбда-выражения и захвачены по ссылке?
Проблема, которую я пытаюсь решить: у меня есть система транзакций базы данных, код которой выглядит примерно так:
std::set<int> values;
auto f = [&](TransactionOp* op) -> Status {
for (auto v : readColumn("values"))
values.insert(v);
return Ok();
}
Status s = TransactionRunner::Run(f);
В приведенном выше коде есть небольшая ошибка, потому что f не очищает значения. TransactionRunner::Run может вызывать f несколько раз, пока транзакция не завершится успешно. Если f не очищает значения, тогда значения будут иметь мусорные значения из предыдущих попыток.
Я пишу аккуратную проверку, чтобы найти такие ошибки и предотвратить появление новых.
Пока у меня есть что-то вроде:
cxxRecordDecl(isLambda(), hasDescendant(cxxMethodDecl(returns(hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl(hasName("Status")))))), parameterCountIs(1), hasParameter(0, hasType(pointsTo(cxxRecordDecl(hasName("TransactionOp"))))), hasBody(compoundStmt(allOf(hasDescendant(cxxMemberCallExpr(on(declRefExpr(to(varDecl().bind("insertee")))), thisPointerType(cxxRecordDecl(hasName("set"))), callee(cxxMethodDecl(hasName("insert"))))), unless(hasDescendant(cxxMemberCallExpr(on(declRefExpr(to(equalsBoundNode("insertee")))), thisPointerType(cxxRecordDecl(hasName("set"))), callee(cxxMethodDecl(hasName("clear"))))))))))))
В приведенном выше примере будет найдена лямбда с правильной подписью, внутри которой есть вставка набора, но нет явного вызова того же набора.
Я хочу, чтобы он не запускался для наборов, объявленных внутри лямбды. Поэтому я бы хотел, чтобы сопоставитель совпадал только в том случае, если набор захвачен лямбдой.