Как сопоставить переменные в лямбда-выражениях, которые определены вне лямбда-выражения и захвачены ссылкой?
Проблема, которую я пытаюсь решить: у меня есть система транзакций базы данных, код которой выглядит примерно так:this:
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 не очищает значения, то значения будут иметь значения мусора от предыдущих попыток.
Я пишу проверку clang-tidy, чтобы найти подобные ошибки и остановить новые записи.
Пока у меня есть что-то вроде:
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"))))))))))))
Выше будет найдена лямбда с правильной сигнатурой, в которой есть вставка набора, но нет явного вызова к тому же набору.
Iхотите, чтобы он не срабатывал на наборах, объявленных внутри лямбды.Поэтому я бы хотел, чтобы совпадение совпадало только в том случае, если набор захватывается лямбдой.