Maison > développement back-end > C++ > Comment initialiser correctement un vecteur avec des types à déplacement uniquement en C ?

Comment initialiser correctement un vecteur avec des types à déplacement uniquement en C ?

DDD
Libérer: 2024-12-17 16:06:11
original
889 Les gens l'ont consulté

How to Correctly Initialize a Vector with Move-Only Types in C  ?

Initialisation de vecteur avec des types à déplacement uniquement

Considérez le code suivant, qui vise à initialiser un vecteur avec des instances std::unique_ptr :

#include <vector>
#include <memory>

int main() {
  using move_only = std::unique_ptr<int>;
  std::vector<move_only> v{move_only(), move_only(), move_only()};
}
Copier après la connexion

Cependant, ce code déclenche une erreur lors de la compilation dans GCC 4.7, car std::unique_ptr ne prend pas en charge la copie et le compilateur tente de créer des copies des pointeurs lors de l'initialisation.

Comportement de GCC

La tentative de GCC de copier les pointeurs peut être considéré comme correct selon la norme C actuelle, qui ne traite pas explicitement des scénarios d'initialisation de liste pour les types de déplacement uniquement comme unique_ptr.

Méthodes d'initialisation alternatives

Pour initialiser correctement un vecteur avec des types de déplacement uniquement, on peut utiliser les approches suivantes :

Utilisation d'itérateurs :

Cette approche consiste à créer un itérateur de déplacement pour la liste d'initialisation et à transmettre au constructeur du vecteur :

#include <iterator>
#include <vector>
#include <memory>

int main() {
  using move_only = std::unique_ptr<int>;
  move_only init[] = {move_only(), move_only(), move_only()};
  std::vector<move_only> v{std::make_move_iterator(std::begin(init)),
                           std::make_move_iterator(std::end(init))};
}
Copier après la connexion

Utilisation de rref_wrapper :

Cette technique utilise un type d'assistance qui fournit un stockage temporaire pour les références de déplacement :

#include <utility>
#include <type_traits>

template<class T>
struct rref_wrapper
{
  explicit rref_wrapper(T&& v) : _val(std::move(v)) {}
  explicit operator T() const { return T{std::move(_val)}; }

private:
  T&& _val;
};

template<class T>
typename std::enable_if<!std::is_lvalue_reference<T>::value,
                         rref_wrapper<T>&>::type
rref(T&& v) {
  return rref_wrapper<T>(std::move(v));
}

template<class T>
void rref(T&) = delete;

int main() {
  using move_only = std::unique_ptr<int>;
  std::initializer_list<rref_wrapper<move_only>> il{rref(move_only()),
                                                  rref(move_only()),
                                                  rref(move_only())};
  std::vector<move_only> v(il.begin(), il.end());
}
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal