1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
|
We already encountered em(structured bindings) in section
ref(STRUCTBIND). Structured bindings allow us to access the fields of
structured types (like tt(structs, std::pair) or (cf. section ref(TUPLES))
tt(tuples)) as local variables inside functions. A basic example using
structured bindings is shown in the following code snippet:
verbinsert(-s4 //binding examples/tie.cc)
Being able to use structured bindings is very useful in cases like these.
But what if we want to assign the fields of a struct to variables that have
already been defined or that were passed to a function via its parameters? In
those situations structured bindings offer no help. E.g., in the following
code snippet a function tt(retrieve) is defined having an tt(int &) parameter
and an tt(int) local variable and we want to assign the values returned by
tt(factory) to those variables:
verb( void retrieve(int &one)
{
int two;
// ... = factory() ??
})
Structured bindings cannot be used here: the elements of structured bindings
cannot be references. Although it em(is) possible to define a tt(std::pair<int
&, int &>) such an object cannot be initialized with the references of tt(one)
and tt(two) which are directly referring to the fields returned by
tt(factory). These statements won't compile:
verb( pair<int &, int &> p{one, two} = factory();
pair<int &, int &>{one, two} = factory();)
While it is possible to first define a tt(pair<int &, int &>) object and then
assign tt(factory's) return value to it, that approach clearly is less elegant
than what's offered by structured bindings:
verb( pair<int &, int &> p{one, two};
p = factory();)
Fortunately, there is a better alternative. After including the tthi(tuple)
header file (see also section ref(TUPLES)) tt(std::tie) is available allowing
us to `tie' references to fields of structured data types. Using tt(std::tie)
it is very easy to associate the variables tt(one) and tt(two) of the function
tt(retrieve) with the fields of the pair returned by tt(factory):
verbinsert(-s4 //retrieve examples/tie.cc)
When Executing these statements:
verbinsert(//stmnts examples/tie.cc)
the following output is obtained:
verb( 0 0
1 2
1 0)
In addition to the above the tt(std::tie) function also supports ordering and
(in)equality comparisons. The tt(struct Data) in the next example defines
three fields: an tt(int), a tt(std::string) and a tt(double). Each of these
fields support ordering and (in)equality comparisons. In those cases, all
comparison operators can easily be implemented through the spaceship
operator (cf. section ref(SPACESHIP)) using tt(std::tie):
verbinsert(-s4 //spaceship examples/tie.cc)
Note that tt(struct Data's) spaceship operator returns tt(partial_ordering)
values (cf. section ref(PARTORD)). Although tt(int) and tt(std::string's)
spaceship operators return tt(strong_ordering) values, tt(double's) spaceship
operator doesn't. Instead it returns tt(partial_ordering)
values. Consequently, tt(struct Data's) spaceship operator also returns
tt(partial_ordering) values.
|