Usando vector como buffer sin inicializarlo en resize ()

Quiero usar vector como buffer. La interfaz es perfecta para mis necesidades, pero hay una penalización de rendimiento al redimensionarla más allá de su tamaño actual, ya que la memoria se inicializa. No necesito la inicialización, ya que los datos serán sobrescritos en cualquier caso por algunas funciones C de terceros. ¿Hay alguna manera o un asignador específico para evitar el paso de inicialización? Tenga en cuenta que sí quiero usar resize() , no otros trucos como reserve() y capacity() , porque necesito size() para representar siempre el tamaño significativo de mi “buffer” en cualquier momento, mientras que capacity() podría ser mayor que su tamaño después de un cambio de resize() , así que, una vez más, no puedo confiar en la capacity() como información significativa para mi aplicación. Además, el (nuevo) tamaño del vector nunca se conoce de antemano, así que no puedo usar std::array . Si vector no se puede configurar de esa manera, me gustaría saber qué tipo de contenedor o asignador podría usar en lugar de vector . El único requisito es que la alternativa al vector debe, como máximo, basarse en STL o Boost. Tengo acceso a C ++ 11.

No hay nada en la biblioteca estándar que cumpla con sus requisitos, y tampoco hay nada que yo sepa de impulso.

Hay tres opciones razonables que puedo pensar:

  • Siga con std::vector por ahora, deje un comentario en el código y vuelva a consultarlo si esto alguna vez causa un cuello de botella en su aplicación.
  • Utilice un asignador personalizado con métodos de construct / destroy vacíos y espere que su optimizador sea lo suficientemente inteligente como para eliminar las llamadas a ellos.
  • Cree un contenedor alrededor de una matriz asignada dinámicamente, implementando solo la funcionalidad mínima que necesita.

Es un problema conocido que la inicialización no se puede desactivar incluso explícitamente para std::vector .

La gente normalmente implementa su propio pod_vector<> que no hace ninguna inicialización de los elementos.

Otra forma es crear un tipo que sea compatible con el diseño con char, cuyo constructor no hace nada:

 struct NoInitChar { char value; NoInitChar() { // do nothing static_assert(sizeof *this == sizeof value, "invalid size"); static_assert(__alignof *this == __alignof value, "invalid alignment"); } }; int main() { std::vector v; v.resize(10); // calls NoInitChar() which does not initialize // Look ma, no reinterpret_cast<>! char* beg = &v.front().value; char* end = beg + v.size(); } 

Encapsularlo

Inicialízalo al tamaño máximo (no reserva).

Mantenga una referencia al iterador que representa el final del tamaño real , como lo expresó.

Use begin y real end , en lugar de end , para sus algoritmos.