Subclause: [basic.def.odr]
Issue description
Bullet 4 of the odr-usability rule in [basic.def.odr] paragraph 10 requires the lambda's block scope to be an intervening scope. But a function contract predicate sits in the lambda-declarator, outside the block scope — so this [expr.prim.lambda] example is ill-formed despite its // OK:
void test() {
int i = 1;
auto f3 = [i] pre(i > 0) {}; // OK, i is captured explicitly.
}
Only bullet 4 can apply to the intervening lambda scope. i is captured, so the first conjunct holds; the second wants the block scope {} to intervene, but pre(i > 0) precedes {}. So i is not odr-usable.
P2900R14 added a contract-assertion scope to the benign-scope list in p10 but missed bullet 4, which still only knows the block scope. So it rejects this explicit-capture lambda contract predicate just as bullet 4 (CWG 2380) deliberately rejects [=](int k = n) {}.
Proposed resolution
Let bullet 4's second conjunct also accept a contract-assertion scope of the lambda-expression:
the intervening scope is the lambda scope of a lambda-expression that has a
simple-capture naming the entity or has a capture-default, and
-the block scope of the lambda-expression
+the block scope of the lambda-expression,
+or a contract-assertion scope [basic.scope.contract] introduced by a function
+contract assertion [dcl.contract.func] of the call operator or operator template
+of that lambda-expression,
is also an intervening scope.
[=](int k = n) {} stays ill-formed, so CWG 2380 is unaffected.
Subclause: [basic.def.odr]
Issue description
Bullet 4 of the odr-usability rule in [basic.def.odr] paragraph 10 requires the lambda's block scope to be an intervening scope. But a function contract predicate sits in the lambda-declarator, outside the block scope — so this [expr.prim.lambda] example is ill-formed despite its
// OK:Only bullet 4 can apply to the intervening lambda scope.
iis captured, so the first conjunct holds; the second wants the block scope{}to intervene, butpre(i > 0)precedes{}. Soiis not odr-usable.P2900R14 added a contract-assertion scope to the benign-scope list in p10 but missed bullet 4, which still only knows the block scope. So it rejects this explicit-capture lambda contract predicate just as bullet 4 (CWG 2380) deliberately rejects
[=](int k = n) {}.Proposed resolution
Let bullet 4's second conjunct also accept a contract-assertion scope of the lambda-expression:
[=](int k = n) {}stays ill-formed, so CWG 2380 is unaffected.