Maison >développement back-end >C++ >Pouvons-nous déplacer en toute sécurité des éléments d'une `std::initializer_list` en C ?

Pouvons-nous déplacer en toute sécurité des éléments d'une `std::initializer_list` en C ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-19 15:03:15358parcourir

Can We Safely Move Elements from a `std::initializer_list` in C  ?

Déplacement d'éléments depuis std::initializer_list

En C , une liste d'initialiseurs, notée std::initializer_list, pose une question concernant le mouvement de son éléments. Pouvons-nous extraire et déplacer en toute sécurité des éléments d’une telle liste ? Examinons le problème.

Dans l'extrait de code ci-dessous, une fonction foo accepte une liste d'initialiseurs comme argument :

#include <initializer_list>
#include <utility>

template<typename T>
void foo(std::initializer_list<T> list)
{
    for (auto it = list.begin(); it != list.end(); ++it)
    {
        bar(std::move(*it)); // Intended to move the element
    }
}

Le problème survient car std::initializer_list présente des caractéristiques uniques qui le distinguent des conteneurs ordinaires. Ses éléments résident dans un tampon temporaire et ne sont pas soumis à la même sémantique de valeur que les conteneurs standard. Cela soulève des doutes quant au potentiel d'un mouvement réussi.

Malheureusement, l'attente d'un mouvement fluide des éléments est infondée. Une tentative de déplacement d'éléments d'une liste d'initialisation produira des résultats inattendus. Au lieu de déplacer les éléments, des copies sont créées. Ce comportement provient du fait que les fonctions de début et de fin dans std::initializer_list renvoie const T *, ce qui donne une référence rvalue immuable notée T const &&.

Par conséquent, l'expression de déplacement utilisée dans bar(std::move(*it)) se lie à un paramètre de fonction de type T const &, préservant efficacement les copies.

La raison de cette limitation est attribuée à la prérogative du compilateur d'instancier std::initializer_list en tant que constante initialisée statiquement. Autoriser les résultats mutables du début à la fin entraverait cette optimisation, introduisant de la complexité dans la conception du compilateur.

Malgré le comportement inattendu, une solution pourrait se profiler à l'horizon. Une [proposition ISO](https://github.com/CaseyCarter/iso-changes/blob/master/icpp/p1716r4.md) cherche à introduire la prise en charge de la liste d'initialisation pour les types de déplacement uniquement. Cet effort vise à améliorer les capacités du langage et à fournir une approche plus cohérente du travail avec les listes d'initialisation et la sémantique de déplacement.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn