Si quiero construir una matriz muy simple como
int myArray[3] = {1,2,3};
¿Debería usar std::array
en su lugar?
std::array<int, 3> a = {{1, 2, 3}};
¿Cuáles son las ventajas de usar std :: array sobre los habituales? ¿Es más eficaz? ¿Simplemente más fácil de manejar para copiar / acceder?
for (auto i = ++std::begin(myArray); . . .
posible que ni siquiera se compile (parece que los temporales de tipo fundamental no son mutables, al menos no con clang 6)struct Direction { int32_t dw; int32_t dh; };
ystatic const Direction DIRECTIONS[DIRECTIONS_COUNT] { { -1, 1}, {0,1}, {1,1} , { 1, 0 }, {1,-1}, {0,-1} , {-1,-1}, {-1,0} };
compila. Pero si cambia a unastd::array<Direction,DIRECTIONS_COUNT>
con la misma lista de inicializadores, de repente aparece el error "demasiados inicializadores". (Comunidad VS 2019 con lenguaje = C ++ 17)std::array
inicialización?Respuestas:
Tiene una semántica de valor amigable, de modo que se puede pasar o devolver de funciones por valor. Su interfaz hace que sea más conveniente encontrar el tamaño y usarlo con algoritmos basados en iteradores de estilo STL.
Debería ser exactamente igual. Por definición, es un agregado simple que contiene una matriz como único miembro.
Si.
fuente
A
std::array
es una envoltura muy delgada alrededor de una matriz de estilo C, básicamente definida comotemplate<typename T, size_t N> class array { public: T _data[N]; T& operator[](size_t); const T& operator[](size_t) const; // other member functions and typedefs };
Es un agregado y le permite usarlo casi como un tipo fundamental (es decir, puede pasar por valor, asignar, etc., mientras que una matriz C estándar no se puede asignar o copiar directamente a otra matriz). Debería echar un vistazo a alguna implementación estándar (saltar a la definición de su IDE favorito o abrir directamente
<array>
), es una parte de la biblioteca estándar de C ++ que es bastante fácil de leer y comprender.fuente
std::array
está diseñado como contenedor de cero sobrecarga para matrices C que le da el valor "normal" como la semántica de los otros contenedores de C ++.No debería notar ninguna diferencia en el rendimiento en tiempo de ejecución mientras aún disfruta de las funciones adicionales.
Usar en
std::array
lugar deint[]
matrices de estilo es una buena idea si tiene C ++ 11 o boost a mano.fuente
La situación parece ser más complicada, ya
std::array
que no siempre produce un código ensamblador idéntico en comparación con C-array dependiendo de la plataforma específica.Probé esta situación específica en godbolt :
#include <array> void test(double* const C, const double* const A, const double* const B, const size_t size) { for (size_t i = 0; i < size; i++) { //double arr[2] = {0.e0};// std::array<double, 2> arr = {0.e0};//different to double arr[2] for some compiler for (size_t j = 0; j < size; j++) { arr[0] += A[i] * B[j]; arr[1] += A[j] * B[i]; } C[i] += arr[0]; C[i] += arr[1]; } }
GCC y Clang producen un código ensamblador idéntico tanto para la versión C-array como para la
std::array
versión.Sin embargo, MSVC e ICPC producen un código de ensamblaje diferente para cada versión de la matriz. (Probé ICPC19 con
-Ofast
y-Os
; MSVC-Ox
y-Os
)No tengo idea de por qué este es el caso (de hecho, esperaría un comportamiento exactamente idéntico de std :: array y c-array). Quizás se empleen diferentes estrategias de optimización.
Como un pequeño extra: parece haber un error en ICPC con
#pragma simd
para la vectorización cuando se usa la matriz c en algunas situaciones (el código de la matriz c produce una salida incorrecta; la
std::array
versión funciona bien).Desafortunadamente, todavía no tengo un ejemplo de trabajo mínimo para eso, ya que descubrí ese problema mientras optimizaba un fragmento de código bastante complicado.
Presentaré un informe de error a intel cuando esté seguro de que no entendí mal algo sobre C-array /
std::array
y#pragma simd
.fuente
std::array
tiene semántica de valor, mientras que las matrices en bruto no. Esto significa que puede copiarlostd::array
y tratarlo como un valor primitivo. Puede recibirlos por valor o referencia como argumentos de función y puede devolverlos por valor.Si nunca copia a
std::array
, entonces no hay diferencia de rendimiento que una matriz sin formato. Si necesita hacer copias, entoncesstd::array
hará lo correcto y aún así debería ofrecer el mismo rendimiento.fuente