Structured bindings for `out` parameters — new in 4162

Structured bindings for out parameters — new in 4162

Short version: if a void function returns values through out parameters, 4162 lets you capture them with a structured binding instead of pre-declaring each variable and passing it into the call.

Here’s a function with two outputs:

void two_param_return(out vector(string) names,
                      out vector(number) quotes,
                      curve_name cn,
                      date d,
                      quote_side qs)
{
    curve c = curve(cn,d,qs);
    names = c.instrument_names();
    quotes = c.instruments().quote();
}

Before 4162 you’d declare the outputs and pass them in as arguments:

vector(string) n;
vector(number) q;
two_param_return(n,q,cn,d,qs);

Now you can leave the out arguments off the call and bind the results directly:

auto [n,q] = two_param_return(cn,d,qs);

The names in the binding map to the out parameters in declaration order, so n is names and q is quotes.

Full working example:

void two_param_return(out vector(string) names,
                      out vector(number) quotes,
                      curve_name cn,
                      date d,
                      quote_side qs)
{
    curve c = curve(cn,d,qs);
    names = c.instrument_names();
    quotes = c.instruments().quote();
}

out void testing_two_param(curve_name cn, date d, quote_side qs)
{
    auto [n,q] = two_param_return(cn,d,qs);
    log_message(log_level.LOG_INFO, n);
    log_message(log_level.LOG_INFO, string(q));
}

Notes

  • Only works for void functions — the values have to come back through out parameters, not a return value.
  • Works for any number of out parameters; the two-output case here just keeps the example short.
  • auto is required. You can’t spell out the binding types explicitly — the parser keys off the auto [ construct.
  • You can bind partially. Bindings fill the out parameters from the left, so you can omit the first out argument (let it be bound) while still passing the second one explicitly — but not the other way around:
vector(number) q;
auto [n] = two_param_return(q,cn,d,qs);

If you’ve used C++, this is the same idea as C++17 structured bindings — including the rule that auto is mandatory and the types can’t be named.