3

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?

1 Answer 1

4

The standard doesn't allow it:

For each entity captured by copy, an unnamed non-static data member is declared in the closure type.

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 this parameter, 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 this in a lambda is to use the interfaces the standard provides: calling the lambda. AKA: recursively calling the lambda without naming the lambda.

Sign up to request clarification or add additional context in comments.

1 Comment

Other than capture of this, one could see extending the standard to say that the captured variables are actually private members with that name I suspect? Then I could see adding a public keyword to lambda, heh.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.