2012-01-31 36 views
12

Me gustaría usar std::array de C++ 11 como un campo de mi propia clase. Toma dos parámetros de plantilla (primero define el tipo de datos, segundo define el tamaño de una matriz).C++ 11 std :: array

Pero conozco el segundo parámetro solo en el constructor. No estoy familiarizado con el estándar C++ 11, pero supongo que es imposible establecer un parámetro de plantilla durante la ejecución.

¿Hay alguna alternativa para std::array? std::vector es probablemente un poco demasiado, porque nunca voy a cambiar el tamaño de la misma.

Respuesta

15

std::vector es lo más simple de usar; aunque como dices, desperdicia algunos bytes si nunca necesitas cambiar el tamaño.

std::unique_ptr<T[]>, inicializado con el resultado de new T[size], sería lo más eficiente; debe tener el mismo tamaño que un puntero y eliminará la memoria asignada cuando se destruya. No es copiable, sin embargo; Tendrás que proporcionar un constructor de copia para tu clase si quieres que se pueda copiar. También es menos conveniente que std::array y std::vector, ya que no tiene la interfaz de un contenedor estándar. Tal vez puedas escribir un contenedor de estilo STL si lo necesitas; pero solo usaría std::vector en ese caso.

+3

Yo diría usar un std :: vector sobre un unique_ptr , el primero es compatible con todas las funciones de biblioteca estándar que funcionan en los iteradores. De hecho, el objetivo de std :: array es proporcionar dicha interfaz sobre una matriz normal. –

+3

@ user1131467: De hecho, 'std :: vector' es mucho más conveniente; pero el OP expresó una preocupación acerca de la eficiencia, por lo que quizás sea importante guardar algunos bytes. –

+0

Si va a escribir un contenedor de estilo STL, al menos también debería saber su tamaño. No puede preocuparse por la capacidad. – UncleBens

6

std :: array es para cuando conoce el tamaño estáticamente en tiempo de compilación. Si no sabe hasta el tiempo de ejecución, use un std :: vector. Si no lo cambia de tamaño, no hay demasiados gastos generales.

class Container 
{ 
    vector<T> v; 
    Container(int i) : v(i) { v.shrink_to_fit(); } 
}; 

Si usted está preocupado por el espacio:

http://en.cppreference.com/w/cpp/container/vector/shrink_to_fit

No estoy seguro si hay una manera de construir el vector ya trimed. No parece ser requerido por el estándar para ser construido, aunque en la práctica muchas implementaciones lo harán.

BTW También puede construir un vector con vector (size_t N, T t) que establecerá cada elemento inicial en t (sin esto, los elementos están construidos por defecto).

+0

IIRC, el vector está construido con * exactamente * la capacidad que usted le solicite. No es necesario encogerse después.El truco de copiar y cambiar para reducir un vector también se basa en eso. – Xeo

+1

Curiosamente, para algunos puntos de referencia, no hay sobrecarga alguna y el código 'std :: vector' produce el mismo código SSE vectorizado que con matrices nativas (con g ++ al menos) –

+0

Creo que se asigna una matriz en su lugar y una el vector se asigna de forma dinámica. –

11

No estoy familiarizado con el estándar C++ 11, pero supongo que es imposible establecer un parámetro de plantilla durante la ejecución.

No se puede pasar de un único valor conocido en tiempo de ejecución como un argumento de plantilla ... el código creado por una de instancias de plantilla tiene que ser creado en tiempo de compilación, por lo que no puede depender de una valor de tiempo de ejecución.

Algunas posibles soluciones son crear especializaciones de plantilla para algunos valores comunes de tamaño de matriz, y luego un posible valor de tamaño máximo. Aunque creo que sería una forma bastante ineficiente de trabajar.

Para ser honesto, en su caso, un std::vector sería la mejor solución, ya que simplemente puede llamar al resize() en el vector para que tenga el tamaño correcto en tiempo de ejecución a través de la asignación dinámica.

+1

o, en lugar de 'resize()', use el constructor 'std :: vector (size_t n)'. –

+2

@phresnel: o 'reserve' + una secuencia de' push_back'/'emplace_back' si no todos sus elementos deben ser iguales. –

3

Si no conoce el tamaño de la matriz hasta el tiempo de ejecución, entonces quiere usar std :: vector.

Cuestiones relacionadas