Y a-t-il une différence entre un std::pair
et un std::tuple
avec seulement deux membres? (Outre l'évidence qui std::pair
nécessite deux et seulement deux membres et tuple
peut avoir plus ou moins ...)
92
Il y a quelques différences:
std::tuple
ne peut jamais être par mise en page standard (du moins, il n'est pas nécessaire que ce soit par la norme). Chacun std::pair<T, Y>
est une disposition standard si les deux T
et Y
sont une disposition standard.
Il est un peu plus facile d'obtenir le contenu d'un pair
fichier tuple
. Vous devez utiliser un appel de fonction dans le tuple
cas, alors que le pair
cas n'est qu'un champ membre.
Mais c'est à peu près tout.
.first
et.second
sont à portée de main, ils offrent aucune aide si un membre tiers (ou plus) (s) sont nécessaires dans un changement de code. J'ai remarqué que j'ai tendance à utiliserstd::get
n'importe quel Getters de cette façon, je n'ai pas besoin de tout changer, juste les types de données et lesmake_pair
appels auxmake_tuple
appels.std::map
utilisestd::pair<const Key,T>
commevalue_type
même dans C ++ 11. Où exactement les tuples sont-ils utilisésstd::map
?std::map
.C'est une réponse très tardive, mais notez que, étant donné qu'elle
std::pair
est définie avec des variables membres, sa taille ne peut pas être optimisée à l'aide de l' optimisation de classe de base vide (first
etsecond
doit occuper des adresses distinctes, même si l'une ou les deux sont une classe vide). Ceci est exacerbé par les exigences d'alignementsecond_type
, donc dans le pire des cas, le résultatstd::pair
sera fondamentalement deux fois la taille nécessaire.std::tuple
n'autorise l'accès que via des fonctions d'assistance, il est donc possible qu'il dérive de l'un ou l'autre type si l'un ou l'autre est vide, ce qui économise la surcharge. L'implémentation de GCC, au moins, fait définitivement cela ... vous pouvez parcourir les en-têtes pour vérifier cela, mais il y a aussi cela comme preuve.la source
[[no_unique_address]]
devrait supprimerstd::pair
l'inconvénient de.Un
std::tuple
nom de plus est (un caractère supplémentaire). Plus de ces caractères sont tapés avec la main droite, donc plus faciles à saisir pour la plupart des gens.Cela dit,
std::pair
ne peut avoir que deux valeurs - pas zéro, une, trois ou plus. DEUX valeurs. Un tuple, cependant, n'a presque aucune limitation sémantique sur le nombre de valeurs. Unstd::pair
, par conséquent, est un type sécurisé de type plus précis à utiliser si vous souhaitez réellement spécifier une paire de valeurs.la source
std::tuple<>
est également de type sécurisé (comment pourrait-il ne pas l'être?), Et2
n'est pas sémantiquement différent depair
.Notez qu'avec C ++ 17, on peut utiliser la même interface pour lire les données de la paire et du tuple avec deux éléments.
auto [a, b] = FunctionToReturnPairOrTuple();
Pas besoin d'utiliser
get<>
:)la source
Pour ce que ça vaut, je trouve que la sortie GDB de std :: tuple est beaucoup plus difficile à lire. Évidemment, si vous avez besoin de plus de 2 valeurs, std :: pair ne fonctionnera pas, mais je considère que c'est un point en faveur des structs.
la source
std::get<0>(tupleName)
dans un getter;GetX()
est beaucoup plus facile à lire et plus court. Il a un petit inconvénient que si vous oubliez de le faire uneconst
personne de méthode peut faire quelque chose de stupide comme ceci:GetX() = 20;
.