J'ai besoin de copier std::set
vers std::vector
:
std::set <double> input;
input.insert(5);
input.insert(6);
std::vector <double> output;
std::copy(input.begin(), input.end(), output.begin()); //Error: Vector iterator not dereferencable
Où est le problème?
assign()
fonction:output.assign(input.begin(), input.end());
Réponses:
Vous devez utiliser un
back_inserter
:std::copy
n'ajoute pas d'éléments au conteneur dans lequel vous insérez: il ne peut pas; il n'a qu'un itérateur dans le conteneur. Pour cette raison, si vous passez directement un itérateur de sortie àstd::copy
, vous devez vous assurer qu'il pointe vers une plage au moins suffisamment grande pour contenir la plage d'entrée.std::back_inserter
crée un itérateur de sortie qui appellepush_back
un conteneur pour chaque élément, de sorte que chaque élément est inséré dans le conteneur. Sinon, vous auriez pu créer un nombre suffisant d'éléments dans lestd::vector
pour contenir la plage en cours de copie:Ou, vous pouvez utiliser le
std::vector
constructeur de plage:la source
output.insert(output.end(), input.begin(), input.end());
place?output.insert(output.cend(), input.cbegin(), input.cend());
-vous? Merci.input,size()
entrées vides, puis ajoutez les ajouts après cela. Je pense que vous voulez utiliserstd::vector<double> output; output.reserve(input.size()); std::copy(...);
.Utilisez simplement le constructeur du vecteur qui prend des itérateurs:
Supposons que vous vouliez juste le contenu de s dans v, et qu'il n'y ait rien dans v avant de copier les données dessus.
la source
voici une autre alternative utilisant
vector::assign
:la source
Vous n'avez pas réservé suffisamment d'espace dans votre objet vectoriel pour contenir le contenu de votre ensemble.
la source
Je pense que le moyen le plus efficace est de préallouer puis de mettre en place des éléments:
De cette façon, nous n'appellerons le constructeur de copie que pour chaque élément au lieu d'appeler d'abord le constructeur par défaut, puis de copier l'opérateur d'affectation pour les autres solutions répertoriées ci-dessus. Plus de précisions ci-dessous.
back_inserter peut être utilisé mais il invoquera push_back () sur le vecteur ( https://en.cppreference.com/w/cpp/iterator/back_insert_iterator ). emplace_back () est plus efficace car elle évite de créer un temporaire lors de l'utilisation de push_back () . Ce n'est pas un problème avec les types construits de manière triviale, mais sera une implication de performance pour les types construits non trivialement (par exemple std :: string).
Nous devons éviter de construire un vecteur avec l'argument size qui fait que tous les éléments sont construits par défaut (pour rien). Comme avec une solution utilisant std :: copy () , par exemple.
Et, enfin, la méthode vector :: assign () ou le constructeur prenant la plage de l'itérateur ne sont pas de bonnes options car ils invoqueront std :: distance () (pour connaître le nombre d'éléments) sur les itérateurs d' ensemble . Cela entraînera l' itération supplémentaire indésirable par les tous définis éléments , car l'ensemble est une structure de données binaires arbre de recherche et il ne met pas en œuvre itérateurs d'accès aléatoire.
J'espère que cela pourra aider.
la source
back_inserter
n'a pas besoin d'être utiliséstd::copy
ne peut pas être utilisé pour insérer dans un récipient vide. Pour ce faire, vous devez utiliser un insert_iterator comme ceci:la source