From declarations / functions / 9.3.4.6 / 6.2 (i apologize on how to cite the specific sentence from standard):
An explicit-object-parameter-declaration is a parameter-declaration with a this specifier. An explicit-object-parameter-declaration shall appear only as the first parameter-declaration of a parameter-declaration-list of either: (6.1) a member-declarator that declares a member function ([class.mem]), or (6.2) a lambda-declarator ([expr.prim.lambda]).
If this as explicit object parameter is permitted from lambda expressions, what will happen when we capture variables at the same time?
Based on my understandings, if we have lambda under the hood:
[x = 2](this auto& func) { x = 4; }();
may have the rough equivalent of:
class lambda01 {
private:
int x;
public:
constexpr lambda01(cons int& x_)
: x{x_} {}
constexpr void operator()(this lambda01& func) {
func.x = 4;
}
};
lambda04 lambda04_obj {2};
lambda04_obj.operator()();
if it's right.
For example no. 1:
int x;
// is it:
[&x](this auto& func){ x = 4; }();
assert(x == 4);
// or:
[&x](this auto& func){ func.x = 2; }();
assert(x == 2);
- Are both expressions valid?
- Is lambda taking l-value object parameter valid?
For example no. 2 that will print arguments in variadic:
[]<typename... Args>(const Args&... args) {
[&](this auto func){
/** ... **/
};
}(1, 2, 3, 4);
From the commented expression, which one is valid?
(std::cout << args << '\n', ...)(std::cout << func.args << '\n', ...)- both
- neither
If the second choice is valid, then that would deserve another question regarding the possible parameter packs in 1 object.
In short, is it valid to use captured variables accessed with dot operator in lambda taking explicit object parameter?
The standard doesn't allow it:
If it's "unnamed", then you can't name it. There's specific language that causes the name of a captured entity to be transformed into a
this-based expression, but that's it.So you can take an explicit
thisparameter, and names of captured entities will automatically use that. But you can't access those variables through the explicit parameter.The only reason to explicitly take
thisin a lambda is to use the interfaces the standard provides: calling the lambda. AKA: recursively calling the lambda without naming the lambda.