C++ 17 has Structured Bindings, what they do is create a temporary object and provide access to the object’s members locally.
struct S{
int a{5};
float b{3.2};
};
auto [x,y] = S();
What happens is we create a temporary S object, and then copy the values memberwise into the binding structure. x now equals 5 and b equals 3.2. the S instance goes away.
Since functions only can return one value normally, to get additional values out, we use by-reference variables.
void f( int& a, float& b ){
a = 10; b = 3.2f;
}
This leads to a programming style where we do two things:
- create variables to hold the return values before the call
- pass the variable to the function as a parameter.
int x=0;
float y=0;
f( x, y );
//x == 10; y = 3.2f;
It has never been glancingly apparent that the values are not only being passed by reference, which is often the case for performance, but they are also output from the function with changed values.
Structured Bindings provides a solution to this potential issue:
auto f(){
int a{10};
float b{3.2f};
return std::make_tuple(a,b);
}
auto [x,y] = f();
Since tuples can have as many parameters as we want, they are an easy way to accomplish creating the return structure for the binding.
In C++11 there is a less effective way to do return type Binding:
int x; float y;
std::tie( x, y ) = f();
Structured Bindings also works with arrays, and can be used to create variable aliases as well.
auto f(){
int a{10};
float b{3.2f};
return std::make_tuple(a,b);
}
auto f2( const int& i ){
return std::make_tuple(std::ref(i));
}
auto [x, y] = f();
auto [r] = f2(x);
++x;
x = r + 1;
//r is a reference to x, x = 12
This does not mean that by-reference should never be used – it should be where appropriate. What it means is that if a variable is just a return argument, and not also a function argument, then maybe it should be passed out via a Structured Binding and not passed in by reference.