Bonita forma de agregar un vector a sí mismo

Quiero duplicar los contenidos del vector y quiero que se adjunten al final del vector original, es decir v[i]=v[i+n] for i=0,2,...,n-1

Estoy buscando una buena manera de hacerlo, no con un bucle. Vi std::vector::insert pero la versión iterativa prohíbe un iterador a *this (es decir, el comportamiento no está definido).

También probé std::copy siguiente manera (pero resultó en una falla de segmentación):

copy( xx.begin(), xx.end(), xx.end());

Guau. Tantas respuestas que están cerca, ninguna con todas las piezas correctas. Necesita resize el resize (o reserve ) y copy_n , junto con recordar el tamaño original.

 auto old_count = xx.size(); xx.resize(2 * old_count); std::copy_n(xx.begin(), old_count, xx.begin() + old_count); 

o

 auto old_count = xx.size(); xx.reserve(2 * old_count); std::copy_n(xx.begin(), old_count, std::back_inserter(xx)); 

Al usar reserve , copy_n es necesario porque el iterador end() apunta un elemento más allá del final … lo que significa que tampoco está “antes del punto de inserción” de la primera inserción, y se vuelve inválido.


23.3.6.5 [vector.modifiers] promete que para insert y push_back :

Observaciones: Causa la reasignación si el nuevo tamaño es mayor que la capacidad anterior. Si no se realiza una reasignación, todos los iteradores y referencias anteriores al punto de inserción permanecen válidos. Si se lanza una excepción que no sea el constructor de copia, mueva el constructor, el operador de asignación o el operador de asignación de movimiento de T o, por cualquier operación de InputIterator, no haya efectos. Si el constructor de movimientos de una T no copiada arroja una excepción, los efectos no se especifican.

Lo haría así:

 #include  #include  #include  int main(int argc, char* argv[]) { std::vector v1 = { 1, 2, 3, 4, 5 }; { std::vector v2(v1.begin(), v1.end()); std::copy(v1.begin(), v1.end(), std::back_inserter(v2)); std::swap(v1, v2); } return 0; } 

EDITAR: Agregué una versión un poco más eficiente.

 #include  #include  #include  int main(int argc, char* argv[]) { std::vector v1 = { 1, 2, 3, 4, 5 }; { typedef std::move_iterator VecMoveIter; std::vector v2(v1); std::copy(VecMoveIter(v1.begin()), VecMoveIter(v1.end()), std::back_inserter(v2)); v1 = std::move(v2); } return 0; } 

Para agregar más de un espacio de duplicados.

  int main() { std::vector V; V.push_back(1); V.push_back(2); int oldSize = V.size(); int newSize = oldSize; int nDupSlot = 4; V.resize(nDupSlot * oldSize); for(int i=0; i<(nDupSlot-1); ++i) { std::copy_n(V.begin(), oldSize, V.begin() + newSize); newSize = newSize + oldSize; } for(int i =0; i 

Salida:

 12121212 

Puede que no sea la forma más efectiva, pero seguro es simple:

 std::vector toAppend(xx); xx.insert(xx.end(), toAppend.begin(), toAppend.end();