In reading this summary of the c++17 final features I was a bit surprised by the section on structured bindings (emphasis mine):
structured bindings
Until now, there was a known trick to abuse std::tie to assign a tuple or pair to different variables directly, instead of having to deal with the result type manually. This was a hack, and also the variables had to exist, now you can declare the variables and initialize them in one line:
auto [a , b , c] = getvalues();
The braces are needed, getvalues returns a tuple. std::pair is not mentioned in the proposal, so its unclear if this works with pair, which is returned by the STL in some insert methods.
I am assuming they refer to this kind of usage of std::tie
int a,b,c;
std::tie(a,b,c) = std::make_tuple(1,2,3);
which I believed to be a recommended practice.
Can someone offer an explanation as to why they are referring to above example as a hack?
A structured binding declaration introduces all identifiers in the identifier-list as names in the surrounding scope and binds them to subobjects or elements of the object denoted by expression. The bindings so introduced are called structured bindings.
#cpp #cpp17. Structured binding allows to initialise multiple entities by members of another object, for instance: struct stb_node { int index = 0; string value; }; stb_node node1{1, "First"}; cout << node1.
So basically, std::tie(a) initializes a data member reference to a . std::tuple<int>(24) creates a data member with value 24 , and the assignment assigns 24 to the data member reference in the first structure. But since that data member is a reference bound to a , that basically assigns 24 to a .
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:
Are structured bindings everything that they could have been? No, but for the most cases they are everything we need.
What is missing?
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.
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
auto minmax_element(It begin, It end) -> [It min_it, It max_it];
auto [min = *min_it, max = *max_it] = minmax_element(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With