如何匹配在 lambda 之外定义并通过引用捕获的 lambda 中的变量?
我要解决的问题:我有一个数据库事务系统,其代码如下所示:
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"))))))))))))
上面将找到一个具有正确签名的 lambda,其中包含一个集合插入,但没有明确调用同一集合。
我希望它不会在 lambda 内声明的集合上触发。所以我希望匹配器仅在集合被 lambda 捕获时才匹配。