Structured Bindings
Structured bindings tend to be dismissed in many discussions online as very minimal improvements to C++. There isn't very much you can do with them that's not on the package, so to speak: returning multiple values, iterating easily over maps, and initializing more than one variable in an if or switch scope.
The point, however, is not what they allow you to do: everything you can do with them you can do without them. The point is how it is done.If we compare:
auto [var, flag] = func();
with, say
auto val = func();
auto var = val.first;
auto flag = val.second;
it's not just that we take one line instead of three to get the same result, it's that the latter code has to pay more attention to how rather than what. It draws attention to the fact that was was returned was a pair.
There are at least three other possible mechanisms behind that first line.
auto val = func();
auto var = val[0];
auto flag = val[1];
(an array)
auto val = func();
auto var = get<0>(val);
auto flag = get<1>(val);
(a tuple, or a class implementing a tuple-like interface)
auto val = func();
auto var = val.var;
auto flag = val.flag;
(a struct)
Even with the use of auto, in all these cases one has one's attention drawn to the mechanics of how the data is structured.
This point gets a little lost when random names are used, as above, to expose mechanisms in a comparison. Programming for clarity would lead to something far more like
auto [customerID, isCurrent] = retrieveCustomerInfo();
In the structured binding version almost everything is about the meaning expressed in the variables, whereas
auto customerInfo = retrieveCustomerInfo();
auto customerID = customerInfo.first;
auto isCurrent = customerInfo.second;
is less clear because it is cluttered.
(Without auto - another big help to clarity - this is worse still. The pair version is
std::pair<std::string,, bool> customerInfo = retrieveCustomerInfo();
std::string customerID = customerInfo.first;
bool isCurrent = customerInfo.second;
and the best clarity probably comes from using a specially-defined class or struct, at the cost of slightly greater wordiness, if there's an overall case for having such a class defined with a broader use:
CustomerInfo customerInfo = retrieveCustomerInfo();
std::string customerID = customerInfo.ID;
bool isCurrent = customerInfo.currentFlag;
Of course, in that case might just make sense to pass around the CustomerInfo struct instead of extracting the values at the call site.)
Comments
Post a Comment