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
.
tuple
pourrait détenir une référence?std::tuple
n'est pas un conteneur, du moins pas dans la terminologie C ++, pas le même que lestd::vector
et les goûts. Par exemple, vous ne pouvez pas itérer de la manière habituelle sur un tuple car il contient différents types d'objets.Cela ne répond en aucun cas à votre question, mais permettez-moi de le poster quand même car C ++ 17 est fondamentalement prêt (avec le support du compilateur), donc tout en vous demandant comment fonctionne le matériel obsolète, il vaut probablement la peine de regarder comment l'actuel, et future, la version de C ++ fonctionne aussi.
Avec C ++ 17, vous pouvez à peu près gratter
std::tie
en faveur de ce que l'on appelle les liaisons structurées . Ils font la même chose (enfin, pas la même chose , mais ils ont le même effet net), bien que vous ayez besoin de taper moins de caractères, cela n'a pas besoin de support de bibliothèque, et vous avez également la possibilité de prendre des références, si cela se trouve être ce que tu veux.(Notez qu'en C ++ 17, les constructeurs effectuent la déduction d'arguments, ce qui
make_tuple
est devenu quelque peu superflu également.)la source
tie
aux liaisons structurées, les liaisons structurées peuvent être utilisées de cette manière sur des types qui ne sont pas constructibles par défaut.std::tie()
c'est beaucoup moins utile depuis C ++ 17, où les liaisons structurées sont généralement supérieures, mais il a toujours des utilisations, y compris l'attribution à des variables existantes (pas simultanément nouvellement déclarées) et de faire de manière concise d'autres choses comme échanger plusieurs variables ou d'autres choses qui doit attribuer des références.