1

Is there any equivalent to structured binding inside the init-capture list in lambda?

I know this is invalid, but is there any way to declare 'i' and 's' without declaring outside of the lambda?

std::pair<int, std::string> p { 1, "two" };

auto f = [[i, s] = p] mutable -> std::pair<int, std::string> {
  ++i;
  s += '_';
  return {i, s};
};

auto print = [&]{ 
  const auto& x = f();
  std::cout << x.first << ": " << x.second << '\n';
};

print();
print();
print();

Output:

1: _
2: __
3: ___
Desmond Gold
  • 1,517
  • 1
  • 7
  • 19

1 Answers1

4

There is no syntax that directly does that.

You can copy the pair and use a structured binding inside the lambda:

auto f = [p]() mutable {
    auto& [i, s] = p;
    
    ++i;
    s += '_';
    return std::make_pair(i, s);
};

(Note that the omission of () in front of mutable is not permitted as of C++20.)

Alternatively, you can use .first and .second directly:

auto f = [i = p.first, s = p.second]() mutable {
    ++i;
    s += '_';
    return std::make_pair(i, s);
};
L. F.
  • 19,445
  • 8
  • 48
  • 82