C++, l'ensemble de la copie de vecteur
J'ai besoin de copier std::set
à 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?
- il est également
assign()
fonction:output.assign(input.begin(), input.end());
- et
insert()
. - votre vecteur est vide. Il existe une multitude de moyens de recours que si, comme les gens sont de pointage ci-dessous.
- assign() veut reserve() la quantité nécessaire de stockage à l'avance. Il va utiliser l'entrée des itérateurs pour déterminer la quantité est nécessaire, à moins que les itérateurs sont strictement InputIterator, auquel cas il va sauter la réservation et le résultat dans les réaffectations sur chaque push_back(). Sur l'extrémité opposée du spectre, BiderectionalIterators permettrait à juste soustraire bout commencer. std::set de itérateurs, cependant, ne sont pas (ils sont ForwardIterator), et c'est malheureux: dans ce cas, affecter() va juste marcher l'ensemble afin de déterminer sa taille -- mauvaises performances sur les grands ensembles.
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser un
back_inserter
:std::copy
ne pas ajouter des éléments dans le conteneur dans lequel vous insérez: il ne peut pas; il ne dispose que d'un itérateur dans le récipient. De ce fait, si vous passez une sortie itérateur directement àstd::copy
, vous devez vous assurer qu'il pointe vers une plage qui est au moins assez grande pour contenir la gamme d'entrée.std::back_inserter
crée une sortie itérateur qui appellepush_back
sur un conteneur pour chaque élément, de sorte que chaque élément est inséré dans le conteneur. Alternativement, vous pourriez avoir créé un nombre suffisant d'éléments dans lestd::vector
de tenir la gamme copié:Ou, vous pouvez utiliser le
std::vector
gamme du constructeur:output.insert(output.end(), input.begin(), input.end());
à la place?output.insert(output.cend(), input.cbegin(), input.cend());
Qu'en pensez-vous? Merci.input,size()
entrées vides, puis ajouter les ajoute après. Je pense que tu veux dire utiliserstd::vector<double> output; output.reserve(input.size()); std::copy(...);
.Juste utiliser le constructeur pour le vecteur qui prend les itérateurs:
Suppose que vous voulez simplement le contenu de s dans v, et il n'y a rien dans v avant de copier les données.
voici une autre alternative à l'aide
vector::assign
:Vous n'avez pas réservé assez de place dans votre objet vectoriel pour maintenir le contenu de votre jeu.
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 suit:Je pense que le moyen le plus efficace est de préallouer et puis emplace éléments:
De cette façon, nous ne invoquer constructeur de copie pour chaque élément par rapport à d'appeler le constructeur par défaut en premier et ensuite copier opérateur d'affectation pour les autres solutions énumérées ci-dessus. Plus de précisions ci-dessous.
back_inserter peut être utilisé, mais il invoquer 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(). Il n'est pas un problème avec trivialement
des types construits, mais une performance implication pour
non-trivialement types construits (par exemple std::string).
Nous avons besoin pour éviter de construire un vecteur avec la taille de l'argument qui
les causes de tous les éléments par défaut construit (pour rien). Comme avec
solution à l'aide de std::copy(), par exemple.
Et, enfin, vecteur::assign() méthode ou le constructeur prenant l'itérateur de la gamme ne sont pas de bonnes options
parce qu'ils vont invoquer std::distance() (pour connaître le nombre d'éléments)
sur ensemble itérateurs. Ce sera la cause indésirables supplémentaires itération
par l'intermédiaire du ensemble éléments parce que le jeu est un Arbre de Recherche Binaire
structure de données et il ne permet pas de mettre en œuvre des itérateurs à accès aléatoire.
Espère que ça aide.
back_inserter
n'a pas besoin d'être utilisé