I can put it simply like that:
In a language where functions can return just one variable
int a,b,c;
std::tie(a,b,c) = function_returning_multiple_values();
is a hack for:
auto [a, b, c] = function_returning_multiple_values();
just as in the hypothetical world where C++ would allow just one parameter for functions
int p1, p2, p3;
p1 = ...;
p2 = ...;
p3 = ...;
function_taking_multiple_params(std::tie_params(p1, p2, p3));
would be a hack for:
function_taking_multiple_params(p1, p2, p3)
You are so accustomed with the C++ restriction that a function can return at most one object, but in fact it is just an artificial language restriction, just as a restriction to accept at most one parameter would be an artificial language restriction.
The std::tie
is a library hack for a missing language feature. And it has some drawbacks:
- the variables need be declared beforehand
- the variable types must be declared explicitly
- Inefficient or can't be used with types that are not default constructible
Are structured bindings everything that they could have been? No, but for the most cases they are everything we need.
What is missing?
- Explicit type for some elements: e.g.:
auto [a, std::string b, c] = foo();
where a
and c
have the type deduced and b
is explicit "std::string"
auto [a, [b1, b2], c] = foo();
where the second returned object from foo
is a tuple
like object.
- Language feature at the return site (bypassing
std::tuple
all together):
auto foo() -> [int, int]
instead of
auto foo() -> std::tuple<int, int>
auto foo() -> [int& key, int& value]
... well... wouldn't that be nice
- and combine that with... - get ready for a cool new name - Generalized return initialization:
auto minmax_element(It begin, It end) -> [It min_it, It max_it];
auto [min = *min_it, max = *max_it] = minmax_element(...);