Pourquoi ne pas std::queue::pop valeur de retour.?
Je suis allé à travers ce page mais je ne suis pas en mesure d'obtenir la raison pour la même chose . Là, il est mentionné que
"il est plus judicieux pour elle de retourner aucune valeur à tous et à exiger
les clients à utiliser avant() pour inspecter la valeur à l'avant de la file d'attente"
Mais d'inspecter un élément de l'avant() est également nécessaire que l'élément à copier dans lvalue. Par exemple, dans ce segment de code
std::queue<int> myqueue;
int myint;
int result;
std::cin >> myint;
myqueue.push (myint);
/* ici temporaires seront créés sur les RHS qui sera affectée à résultat, et dans le cas
si les rendements par référence alors le résultat sera invalidée après pop opération */
result = myqueue.front(); //result.
std::cout << ' ' << result;
myqueue.pop();
sur la cinquième ligne cout objet crée d'abord une copie de myqueue.avant() attribue alors que le résultat. Alors, quelle est la différence, de la pop de la fonction aurait pu faire la même chose.
void std::queue::pop();
).La question a été posée, mais comme une note: si vous voulez vraiment une pop qui renvoie, elle peut être facilement mise en œuvre avec un libre de la fonction: ideone.com/lnUzf6
Votre lien est à la STL de la documentation. Mais vous vous posez sur le C++ de la bibliothèque standard. Des choses différentes.
"Mais d'inspecter un élément de
front()
aussi nécessaire que l'élément à copier dans lvalue" - non, il ne le fait pas. front
renvoie une référence, pas une valeur. Vous pouvez inspecter la valeur qu'elle renvoie sans le copier.le modèle que vous décrivez exige une copie. Peut-être. Si vous voulez multiplex de la consommation de la file d'attente, alors oui, vous devez faire une copie avant de relâcher le verrou sur la file d'attente. Toutefois, si vous ne se soucient que de séparer l'entrée et la sortie, alors vous n'avez pas un verrou pour inspecter l'avant. Vous pourriez vous attendre à verrou jusqu'à ce que vous êtes fait de les consommer et de besoin d'appeler
pop()
. Si vous utilisez std::queue<T, std::list<T>>
alors il n'y a aucune inquiétude à propos de la référence fournie à partir de front()
être invalidées par une push()
. Mais vous devez vous votre modèle d'utilisation et doit documenter vos contraintes.OriginalL'auteur cbinder | 2014-07-30
Vous devez vous connecter pour publier un commentaire.
Il pourrait en effet avoir fait la même chose. La raison pour laquelle il n'a pas, en effet, une pop qui a retourné le sauté élément est dangereux en présence d'exceptions (retour par valeur et donc la création d'une copie).
Envisager ce scénario (avec un naïf/composé pop de mise en œuvre, à ilustrate mon point de vue):
Si le constructeur de copie de T lance sur le retour, vous avez déjà modifié l'état de la file d'attente (
top_position
dans mon implémentation naïve) et l'élément est supprimé de la file d'attente (et n'est pas retourné). Pour toutes fins utiles (peu importe comment vous intercepter l'exception dans le code client) de l'élément en haut de la file d'attente est perdu.Cette mise en œuvre est également inefficace dans le cas où vous n'avez pas besoin de le sauté de la valeur (c'est à dire qu'il crée une copie de l'élément que personne ne pourra l'utiliser).
Cela peut être mis en œuvre efficacement et en toute sécurité, avec deux opérations distinctes (
void pop
etconst T& front()
).C++11 remarque: si T a un bas prix noexcept déplacez-constructeur (ce qui est souvent le cas pour la nature des objets mis en piles) puis retour par valeur est efficace et garanti sans exception.
Je ne dis pas que tous les changements, mon point est que certains de ces inconvénients deviennent de moins en moins un problème de C++11.
Mais pourquoi est-il appelé
pop
? c'est assez contre-intuitif. Il pourrait être nommédrop
, et puis il est clair pour tous qu'il ne se déclenche pas un élément, mais il tombe à la place...le gouvernement de facto "pop" opération a toujours été de tenir le haut de l'élément à partir d'une pile et de le retourner. Quand je suis arrivé dans STL piles, j'ai été surpris, pour dire le moins, sur
pop
pas de retourner quoi que ce soit. Voir par exemple sur wikipédia.OriginalL'auteur utnapistim
La page que vous avez lié à des réponses à votre question.
De citer l'ensemble de la section pertinente:
C++ est conçu dans un souci d'efficacité, sur le nombre de lignes de code, le programmeur doit écrire.
pop
qui renvoie une valeur.OriginalL'auteur BPF2010
pop ne peut pas renvoyer une référence à la valeur qui est retiré, puisqu'il est retiré de la structure des données, de sorte quelle devrait être la référence? Il pourrait revenir à la valeur, mais que faire si le résultat de la pop n'est pas stocké n'importe où? Puis le temps est gaspillé, copie de la valeur inutilement.
pop
retourne et la loi du retour peut provoquer une exception. Il aurait évidemment pour supprimer l'élément avant il retourne, et puis si quelque chose de jette, l'élément peut être irrémédiablement perdu.Cette préoccupation s'appliquent toujours à f.j'. un noexcept constructeur de déplacement? (Bien sûr 0 copies sont plus efficaces que les deux mouvements, mais qui pourrait ouvrir la porte à une exception sécuritaire, efficace combiné avant+pop)
vous pourriez revenir en valeur si vous connaissez la
value_type
a un nothrow constructeur de déplacement, mais la file d'attente de l'interface serait alors différente selon le type d'objet à stocker, ce qui ne serait pas utile.Qui serait à l'abri, mais la pile est une bibliothèque générique de la classe et, par conséquent, plus il a à assumer sur le type de l'élément le moins utile qu'il est.
Je sais que la STL ne permettent pas de le faire, mais cela signifie que l'on peut construire son propre classe de file d'attente avec le blackjack et le ^W^W^W avec cette fonction 🙂
OriginalL'auteur Neil Kirk
Avec l'implémentation actuelle, ceci est valable:
Si pop serait de retour une référence, comme ceci:
Ensuite le code suivant pourrait accident, étant donné que la référence n'est plus valable:
D'autre part, si elle doit retourner une valeur directement:
Ensuite, vous devez faire une copie pour que ce code fonctionne, ce qui est moins efficace:
OriginalL'auteur Jan Rüegg
À partir de Cx11 il serait possible d'archiver comportement souhaité à l'aide de la sémantique de déplacement. Comme pop_and_move. Donc, constructeur de copie ne sera pas appelé, et les performances dépendent constructeur de déplacement seulement.
OriginalL'auteur Slavik Putsenko
Vous pouvez tout à fait faire cela:
Ou, si vous voulez la valeur dans une variable, utilisez une référence:
Suivante: l'expression "plus raisonnable" est une forme subjective de "nous nous sommes penchés sur les habitudes d'utilisation et trouvé plus besoin pour un split". (Rassurez-vous: le langage C++ n'évolue pas à la légère...)
OriginalL'auteur xtofl
Je pense que la meilleure solution serait d'ajouter quelque chose comme
où la valeur recevrez le sauté de valeur.
L'avantage est qu'il pourrait être mis en œuvre à l'aide d'un opérateur d'assignation de déplacement, tout en utilisant l'avant + pop va en faire une copie.
OriginalL'auteur Masse Nicolas