Necesito copiar std::set
a 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
¿Dónde está el problema?
assign()
función:output.assign(input.begin(), input.end());
Respuestas:
Necesitas usar un
back_inserter
:std::copy
no agrega elementos al contenedor en el que está insertando: no puede; solo tiene un iterador en el contenedor. Debido a esto, si pasa un iterador de salida directamentestd::copy
, debe asegurarse de que apunte a un rango que sea al menos lo suficientemente grande como para contener el rango de entrada.std::back_inserter
crea un iterador de salida que llamapush_back
a un contenedor para cada elemento, por lo que cada elemento se inserta en el contenedor. Alternativamente, podría haber creado un número suficiente de elementos en elstd::vector
para mantener el rango que se copia:O bien, puede usar el
std::vector
constructor de rango:fuente
output.insert(output.end(), input.begin(), input.end());
?output.insert(output.cend(), input.cbegin(), input.cend());
¿Qué le parece? Gracias.input,size()
entradas vacías y luego agrega los anexos después de eso. Creo que te refieres a usarstd::vector<double> output; output.reserve(input.size()); std::copy(...);
.Simplemente use el constructor para el vector que toma iteradores:
Asume que solo desea el contenido de s en v, y no hay nada en v antes de copiar los datos.
fuente
Aquí hay otra alternativa usando
vector::assign
:fuente
No ha reservado suficiente espacio en su objeto vectorial para contener el contenido de su conjunto.
fuente
Creo que la forma más eficiente es preasignar y luego colocar elementos:
De esa manera, solo invocaremos el constructor de copia para cada elemento en lugar de llamar primero al constructor predeterminado y luego al operador de asignación de copia para otras soluciones enumeradas anteriormente. Más aclaraciones a continuación.
se puede usar back_inserter pero invocará push_back () en el vector ( https://en.cppreference.com/w/cpp/iterator/back_insert_iterator ). emplace_back () es más eficiente porque evita crear un temporal cuando se usa push_back () . No es un problema con los tipos construidos trivialmente, pero será una implicación de rendimiento para los tipos construidos no trivialmente (por ejemplo, std :: string).
Tenemos que evitar construir un vector con el argumento de tamaño que hace que todos los elementos se construyan por defecto (para nada). Al igual que con la solución usando std :: copy () , por ejemplo.
Y, finalmente, el método vector :: asignar () o el constructor que toma el rango del iterador no son buenas opciones porque invocarán std :: distance () (para conocer el número de elementos) en los iteradores establecidos . Esto hará que la iteración adicional no deseada a través de los todos los establecidos los elementos, porque el conjunto es la estructura de datos de árbol de búsqueda binaria y no implementa iteradores de acceso aleatorio.
Espero que ayude.
fuente
back_inserter
no es necesario utilizar astd::copy
no se puede usar para insertar en un contenedor vacío. Para hacer eso, necesita usar un insert_iterator así:fuente