Afin de clarifier le concept de base, réduisons-le à un exemple plus basique. Bien que cela std::tie
soit utile pour les fonctions retournant (un tuple de) plus de valeurs, nous pouvons le comprendre très bien avec une seule valeur:
int a;
std::tie(a) = std::make_tuple(24);
return a; // 24
Ce que nous devons savoir pour aller de l'avant:
La prochaine étape consiste à se débarrasser de ces fonctions qui ne font que vous gêner, afin que nous puissions transformer notre code en ceci:
int a;
std::tuple<int&>{a} = std::tuple<int>{24};
return a; // 24
L'étape suivante consiste à voir exactement ce qui se passe à l'intérieur de ces structures. Pour cela, je crée 2 types de T
substituant pour std::tuple<int>
et Tr
substituant std::tuple<int&>
, dépouillés au strict minimum pour nos opérations:
struct T { // substituent for std::tuple<int>
int x;
};
struct Tr { // substituent for std::tuple<int&>
int& xr;
auto operator=(const T& other)
{
// std::get<I>(*this) = std::get<I>(other);
xr = other.x;
}
};
auto foo()
{
int a;
Tr{a} = T{24};
return a; // 24
}
Et enfin, j'aime me débarrasser des structures toutes ensemble (enfin, ce n'est pas 100% équivalent, mais c'est assez proche pour nous, et assez explicite pour le permettre):
auto foo()
{
int a;
{ // block substituent for temporary variables
// Tr{a}
int& tr_xr = a;
// T{24}
int t_x = 24;
// = (asignement)
tr_xr = t_x;
}
return a; // 24
}
Donc, fondamentalement, std::tie(a)
initialise une référence de membre de données à a
. std::tuple<int>(24)
crée un membre de données avec une valeur 24
et l'affectation affecte 24 à la référence de membre de données dans la première structure. Mais depuis que membre de données est une référence liée à a
, que , fondamentalement , cède 24
à a
.