c++ - ejemplo - std::array
¿Contenedor AWL no copiado alrededor de una matriz existente? (5)
¿Es posible crear un contenedor similar a STL, o incluso solo un iterador de estilo STL, para una matriz existente de elementos de tipo POD?
Por ejemplo, supongamos que tengo una matriz de enteros. Sería conveniente poder llamar a algunas de las funciones STL, como find_if, count_if, o ordenarlas directamente en esta matriz.
Sin solución: copiar toda la matriz, o incluso solo referencias a los elementos. El objetivo es ahorrar mucha memoria y tiempo y, a la vez, permitir el uso de otros algoritmos STL.
Puede invocar muchos de los algoritmos STL directamente en una matriz de estilo C regular; fueron diseñados para que funcionen. p.ej,:
int ary[100];
// init ...
std::sort(ary, ary+100); // sorts the array
std::find(ary, ary+100, pred); find some element
Creo que verás que la mayoría de las cosas funcionan como cabría esperar.
Puede usar una plantilla de función en línea para que no tenga que duplicar el índice de matriz
template <typename T, int I>
inline T * array_begin (T (&t)[I])
{
return t;
}
template <typename T, int I>
inline T * array_end (T (&t)[I])
{
return t + I;
}
void foo ()
{
int array[100];
std::find (array_begin (array)
, array_end (array)
, 10);
}
Un puntero es un modelo válido de un iterador:
struct Bob
{ int val; };
bool operator<(const Bob& lhs, const Bob& rhs)
{ return lhs.val < rhs.val; }
// let''s do a reverse sort
bool pred(const Bob& lhs, const Bob& rhs)
{ return lhs.val > rhs.val; }
bool isBobNumberTwo(const Bob& bob) { return bob.val == 2; }
int main()
{
Bob bobs[4]; // ok, so we have 4 bobs!
const size_t size = sizeof(bobs)/sizeof(Bob);
bobs[0].val = 1; bobs[1].val = 4; bobs[2].val = 2; bobs[3].val = 3;
// sort using std::less<Bob> wich uses operator <
std::sort(bobs, bobs + size);
std::cout << bobs[0].val << std::endl;
std::cout << bobs[1].val << std::endl;
std::cout << bobs[2].val << std::endl;
std::cout << bobs[3].val << std::endl;
// sort using pred
std::sort(bobs, bobs + size, pred);
std::cout << bobs[0].val << std::endl;
std::cout << bobs[1].val << std::endl;
std::cout << bobs[2].val << std::endl;
std::cout << bobs[3].val << std::endl;
//Let''s find Bob number 2
Bob* bob = std::find_if(bobs, bobs + size, isBobNumberTwo);
if (bob->val == 2)
std::cout << "Ok, found the right one!/n";
else
std::cout << "Whoops!/n";
return 0;
}
Todos los algoritmos STL usan iteradores.
Un puntero es un iterador válido en una matriz de objetos.
NB El iterador final debe ser un elemento más allá del final de la matriz. De ahí los datos + 5 en el siguiente código.
#include <algorithm>
#include <iostream>
#include <iterator>
int main()
{
int data[] = {4,3,7,5,8};
std::sort(data,data+5);
std::copy(data,data+5,std::ostream_iterator<int>(std::cout,"/t"));
}
Puede usar Boost.Array para crear un tipo de matriz C ++ con semántica STL.
usando arreglos:
int a[100];
for (int i = 0; i < 100; ++i)
a[i] = 0;
usando boost.arrays:
boost::array<int,100> a;
for (boost::array<int,100>::iterator i = a.begin(); i != a.end(); ++i)
*i = 0;
Actualización: con C ++ 11, ahora puede usar std::array
.