Search code examples
c++structured-bindings

How to emulate structured binding init-capture in lambda C++?


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: ___

Solution

  • 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);
    };