En lisant ce résumé des dernières fonctionnalités du c ++ 17, j’ai été un peu surpris par la section sur les liaisons structurées (c’est moi qui souligne):
liaisons structurées
- L'utilisation de `std :: get ` sur un `std :: tuple` est-elle garantie pour les threads pour différentes valeurs de` I`?
- Quelle est la raison de `std :: make_tuple`?
- Arguments du constructeur à partir du tuple
- Configuration requirejse pour std :: ignore
- Confondu par la description par défaut du constructeur de std :: tuple dans la norme ISO C ++
Jusqu’à présent, il était connu d’utiliser un truc pour abuser de std :: tie afin d’affecter directement un tuple ou une paire à différentes variables, au lieu de devoir traiter le type de résultat manuellement. C’était un hack , et les variables devaient exister, maintenant vous pouvez les déclarer et les initialiser sur une seule ligne:
auto [a, b, c] = getvalues ();
Les accolades sont nécessaires, getvalues renvoie un tuple. std :: pair n’est pas mentionné dans la proposition. Par conséquent, il est difficile de savoir si cela fonctionne avec pair, qui est renvoyé par la STL dans certaines méthodes d’insertion.
Je suppose qu’ils font référence à ce type d’utilisation de std::tie
int a,b,c; std::tie(a,b,c) = std::make_tuple(1,2,3);
que je croyais être une pratique recommandée.
Quelqu’un peut-il offrir une explication de la raison pour laquelle ils se réfèrent à l’exemple ci-dessus comme un piratage?
Je peux le dire simplement comme ça:
Dans un langage où les fonctions peuvent renvoyer une seule variable
int a,b,c; std::tie(a,b,c) = function_returning_multiple_values();
est un hack pour:
auto [a, b, c] = function_returning_multiple_values();
tout comme dans le monde hypothétique où C ++ autoriserait un seul paramètre pour les fonctions
int p1, p2, p3; p1 = ...; p2 = ...; p3 = ...; function_taking_multiple_params(std::tie_params(p1, p2, p3));
serait un hack pour:
function_taking_multiple_params(p1, p2, p3)
Vous êtes tellement habitué à la ressortingction C ++ qu’une fonction peut renvoyer au plus un object, mais c’est en fait une ressortingction de langue artificielle, tout comme une ressortingction à accepter au plus un paramètre serait une ressortingction de langue artificielle.
std::tie
est un hack de bibliothèque pour une fonctionnalité de langue manquante. Et cela présente des inconvénients:
Les liaisons structurées sont-elles tout ce qu’elles auraient pu être? Non, mais dans la plupart des cas, ils représentent tout ce dont nous avons besoin.
Que manque-t-il?
auto [a, std::ssortingng b, c] = foo();
où a
et c
ont le type déduit et b
est explicite “std :: ssortingng”
auto [a, [b1, b2], c] = foo();
où le deuxième object renvoyé de foo
est un object semblable à un tuple
.
std::tuple
tous ensemble): auto foo() -> [int, int]
au lieu de
auto foo() -> std::tuple
auto foo() -> [int& key, int& value]
… bien … ça ne serait pas gentil
auto minmax_element(It begin, It end) -> [It min_it, It max_it]; auto [min = *min_it, max = *max_it] = minmax_element(...);
std::tie
en soi une autre fonctionnalité.
Il était destiné à créer un tuple avec des références à des variables
Crée un tuple de références lvalue à ses arguments ou instances de std :: ignore.
Ceci est utile pour créer des n-uplets à la volée sans avoir à copier les variables car ce sont des références. Je prends juste l’exemple de cppreference pour un cas d’utilisation.
bool operator<(const S& rhs) const { // compares n to rhs.n, // then s to rhs.s, // then d to rhs.d return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d); }
Ici, les n-uplets sont créés mais ils ne copient pas les variables mais ont des références.
Maintenant, parce qu'ils contiennent des références, vous pouvez le "pirater" pour faire quelque chose comme ça
int a,b,c; std::tie(a,b,c) = std::make_tuple(1,2,3);
Il assigne les valeurs du tuple retourné à celui avec les références en lui-même.
Ceci est même sur cpprefence juste mentionné comme une "note"
std :: tie peut être utilisé pour décompresser un std :: pair car std :: tuple a une affectation de conversion à partir de paires
Donc, dans c ++ 11 n’était pas vraiment un moyen officiel d’atsortingbuer directement des valeurs, mais std::tie
peut être utilisé comme cela, mais peut-être n’a-t-il jamais été conçu de cette manière.
Ils ont donc introduit la nouvelle "liaison structurée".
Que std::tie
été conçu pour être utilisé de cette façon ou qu'il s'agisse d'un "hack" peut constituer un avis personnel, je suppose que les personnes qui ont présenté std::tie
savent le mieux. Mais compte tenu du type de liaison structuré qui remplace std::tie
dans ce cas, ils ont proposé une solution qui leur semble meilleure.