2012-05-07 14 views
7

Esto es presumiblemente una simple pregunta de C++, pero estoy volviendo a aprender C++ y no sé algunos de los conceptos básicos. Tengo una clase que incluye una estructura con un vector de objetos en él, así que algo como esto:agregar al vector sin copiar los datos de la estructura

struct my_struct{ 
    Irrelevant_Object object, 
    vector<tuple> tuple_list; 
} 

La estructura y la tupla (otra estructura) están predefinidos por la arquitectura y que me han dado en mi método; así que no puedo cambiarlos. Quiero generar e insertar una tupla en la lista original vacía tuple_list.

La solución simple es tener un método que asigne un nuevo objeto de tupla, rellene los datos de tupla, luego llame a tuple_list.push_back() y pase la tupla asignada. Pero esto requeriría asignar una nueva tupla solo para que el método push_back copie todos los contenidos de la estructura tuple (grande) en un espacio de memoria ya definido del vector. Así que estoy pagando el gasto de una asignación/eliminación, así como el menor gasto de copiar el contenido de la tupla en el vector para hacerlo de esta manera. Parece bastante ineficiente, y dado que este método estaría en la ruta crítica de la función, preferiría algo más rápido (admito que dudo que este método sea el cuello de botella, y sé que la optimización temprana == malo. Sin embargo, estoy haciendo esta pregunta más para aprender algo sobre la sintaxis de C++, luego de una necesidad desesperada de hacer esto en mi código).

Así que mi pregunta es, ¿hay una forma más rápida de llenar el contenido de mi lista de tuplas sin asignar y copiar una tupla? Si esto fuera una matriz, podría hacer la matriz tan grande como quisiera, y luego pasar una referencia a tuple_list [0] a la función que crea la tupla. De esta forma, la función podría llenar los contenidos vacíos de la tupla ya asignada dentro de la matriz sin asignar una nueva o copiar de una a otra. Intenté hacer eso con el vector por curiosidad y terminé con una falla seg cuando mi itterator apuntaba a 0x0, así que supongo que la sintaxis no funciona para los vectores. Entonces, ¿hay una manera rápida de hacer esta tarea?

Dado que esta es una pregunta tanto para aprender el idioma como para el uso real, no dude en incluir cualquier otra cosa tangencialmente relevante que considere interesante, estoy buscando aprender.

Gracias.

+0

Echa un vistazo a los constructores sobrecargados de 'std :: vector' y proporciona una lista de constructores y de inicializadores para tu estructura, tal vez?De lo contrario, siempre puede "reservar" su vector en el espacio que necesita para que la llamada 'push_back' use el espacio disponible y no tenga un costo de asignación tan alto. Se necesita un ejemplo más tangible y un caso de uso para proporcionar una respuesta real. – AJG85

Respuesta

15

En C++ 11, puede usar std::vector::emplace_back, que construye el nuevo objeto en el lugar, por lo tanto, no hay copia cuando utiliza este método.

Mediante el uso de este método, se puede hacer esto:

my_struct some_struct; 
some_struct.tuple_list.emplace_back(1, 5, "bleh"); 

Asumiendo que su objeto tuple contiene este constructor:

tuple::tuple(int, int, const std::string&) 

Editar: También se puede utilizar para almacenar una move semantics pre tupla asignada:

my_struct some_struct; 
tuple a_tuple; 
/* modify a_tuple, initialize it, whatever... */ 
some_struct.push_back(std::move(a_tuple)); // move it into your vector 

O utilizar una referencia a la tuple después de que haya sido almacenado en el vector:

my_struct some_struct; 
some_struct.tuple_list.emplace_back(1, 5, "bleh"); 
// store a reference to the last element(the one we've just inserted) 
tuple &some_tuple = some_struct.tuple_list.back(); 
some_tuple.foo(); 

En todas las soluciones anteriores que está creando una sola tuple al mismo tiempo evitar la copia.

+0

esto es casi exactamente lo que quiero (suponiendo que tengamos C++ 11 instalado, lo verificaré dos veces). Sin embargo, dado que la tupla es grande, preferiría pasar una referencia de la tupla del vector (o espacio asignado para la tupla) a un método y construir el contenido en un elemento variable a la vez. ¿Hay algún método similar que devuelva una referencia a la tupla preasignada que puedo usar en su lugar? – dsollen

+0

Ahí va, editó la respuesta: D. – mfontanini

+0

¡excelente respuesta! gracias. – dsollen

Cuestiones relacionadas