2009-05-05 13 views
12

Al usar C++ y el STL, ¿alguien sabe cómo almacenar matrices de enteros como nodos en una lista o vector STL? Tengo una cantidad desconocida de pares de números que necesito almacenar, y al venir de otros idiomas, lo primero que pensé fue utilizar algún tipo de estructura de datos similar a una lista o vector ... pero me estoy metiendo en problemas. Estoy 100% seguro de que estoy cometiendo un error obvio de C++ para principiantes, y que alguien que realmente conozca el idioma echará un vistazo a lo que estoy tratando de hacer y podrá aclararme.¿Cómo almaceno arreglos en una lista STL?

Por lo tanto, esto es lo que he intentado. La declaración de una lista como tal funciona:

stl::list<int[2]> my_list; 

Y entonces puedo hacer fácilmente una serie de dos elementos, así:

int foo[2] = {1,2}; 

Esto compila y funciona muy bien. Sin embargo, tan pronto como intento agregar foo a mi lista, así:

my_list.push_back(foo); 

me sale todo un conjunto retorcido de errores del compilador, ninguno de los cuales realmente entiendo (mi C++ - fu es casi inexistente):

/usr/include/c++/4.0.0/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Tp*, const _Tp&) [with _Tp = int [2]]’: 
/usr/include/c++/4.0.0/bits/stl_list.h:440: instantiated from ‘std::_List_node<_Tp>* std::list<_Tp, _Alloc>::_M_create_node(const _Tp&) [with _Tp = int [2], _Alloc = std::allocator<int [2]>]’ 
/usr/include/c++/4.0.0/bits/stl_list.h:1151: instantiated from ‘void std::list<_Tp, _Alloc>::_M_insert(std::_List_iterator<_Tp>, const _Tp&) [with _Tp = int [2], _Alloc = std::allocator<int [2]>]’ 
/usr/include/c++/4.0.0/bits/stl_list.h:773: instantiated from ‘void std::list<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = int [2], _Alloc = std::allocator<int [2]>]’ 
test.cpp:5: instantiated from here 
/usr/include/c++/4.0.0/ext/new_allocator.h:104: error: ISO C++ forbids initialization in array new 

Entonces, ¿alguien tiene ideas sobre lo que estoy haciendo mal aquí? Cualquier puntero (sin juego de palabras) sería de gran ayuda. ¿No es posible almacenar matrices en una std :: list? ¿Debo usar una estructura? ¿Me falta un * o &?

Respuesta

9

No se puede almacenar matrices en contenedores STL. Utilizarías un vector de vectores o somesuch para el caso general. Para su caso específico, usaría un vector de std :: pair, así: std::vector<std::pair<int, int> >. std::pair es una clase que tiene dos miembros, first y second, del tipo que lo personalices.

Editar: Originalmente lo tenía como std::vector<std::pair<int> >, pero no estaba seguro de si estaba sobrecargado para aceptar solo 1 parámetro en el caso de que ambos tipos fueran iguales ... un poco de excavación no mostró evidencia de esto, entonces lo modifiqué para declarar explícitamente que ambos first y second son int s.

+1

La definición en el estándar no proporciona un tipo predeterminado para el segundo tipo, por lo que debe proporcionar explícitamente ambos tipos. –

23

La cosa almacenada en un contenedor de biblioteca estándar debe ser asignable y copiable, las matrices no son ni lo uno ni lo otro. Su mejor apuesta es crear una lista de std :: vector. Alternativamente, se puede envolver la matriz en una estructura:

struct A { 
    int array[2]; 
}; 

std::list <A> alist; 
+0

¿Cómo empujar a la matrices en 'alist'? – JFA

7

Esta es una buena situación para usar boost::array en lugar de las matrices de estilo C "clásicas". Esto debería funcionar:

std::list<boost::array<int,2> > my_list; 
boost::array<int,2> foo={{1,2}}; 
my_list.push_back(foo); 
5

me gustaría sugerir que utiliza std :: pair para almacenar los valores en este caso. Se encuentra en
<utility>.

Puede almacenar punteros en las matrices de la lista, pero luego deberá ocuparse de toda la administración de la memoria. Usar pares es mucho más simple si solo necesitas pares de valores.

1

A partir de C++ 11, podemos hacer esto con el estándar std::array:

#include <array> 
#include <list> 
#include <iostream> 

int main() { 
    std::list<std::array<int, 2>> l {{3,4},{5,6}}; 
    l.push_back({1,2}); 

    for (const auto &arr : l) 
     for (const auto &v : arr) 
      std::cout << v << ' '; 
} 

o

l.push_back({{1,2}}); 

etc para silenciar alguna advertencia sonido metálico.

Salida:

3 4 5 6 1 2 
1

con C++ 11 hay un ::std::array wrapper disponibles que se pueden utilizar con los contenedores estándar de esta manera:

#include <array> 
#include <iostream> 
#include <list> 
#include <cstdint> 

int 
main() 
{ 
    using t_Buffer = ::std::array<::std::int32_t, 2>; 
    using t_Buffers = ::std::list<t_Buffer>; 
    t_Buffers buffers; 
    buffers.emplace_back(t_Buffer{1, 2}); 
    ::std::cout << buffers.front()[0] << " " << buffers.front()[1] << ::std::endl; 
    return(0); 
} 

Run this code online

Cuestiones relacionadas