2009-05-05 2 views
12

A l'aide de C++ et de la STL, quelqu'un sait-il comment stocker des tableaux entiers sous forme de nœuds dans une liste ou un vecteur STL? J'ai un nombre inconnu de paires de nombres que je dois stocker, et venant d'autres langues, ma première pensée a été d'utiliser une sorte de structure de données semblable à une liste ou à un vecteur ... mais j'ai des problèmes. Je suis sûr à 100% que je fais une erreur évidente de débutant en C++, et que quelqu'un qui connaît réellement la langue jettera un coup d'oeil à ce que j'essaye de faire et sera capable de me mettre d'accord.Comment stocker des tableaux dans une liste STL?

Alors, voici ce que j'ai essayé. Déclarant une liste comme si fonctionne:

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

Et puis je peux facilement faire un tableau à deux éléments, comme ceci:

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

Cette compile et fonctionne très bien. Cependant, dès que j'essaie d'ajouter foo à ma liste, comme suit:

my_list.push_back(foo); 

Je reçois un ensemble noueux d'erreurs du compilateur, aucune dont je comprends vraiment (mon C++ - fu est presque inexistante):

/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 

Alors, quelqu'un a des idées sur ce que je fais mal ici? Tout pointeur (sans jeu de mots) serait très utile. Est-il simplement impossible de stocker des tableaux dans une liste std ::? Dois-je utiliser une structure? Suis-je en train de manquer un * ou un & quelque part?

Répondre

9

Vous ne pouvez pas stocker des tableaux dans des conteneurs STL. Vous utiliseriez un vecteur de vecteurs ou quelque chose pour le cas général. Pour votre cas particulier, j'utiliserais un vecteur de std :: pair, comme ceci: std::vector<std::pair<int, int> >. std::pair est une classe qui a deux membres, first et second, de quelque type que vous le templiez pour être. Edit: Je l'avais initialement comme std::vector<std::pair<int> >, mais je ne savais pas si elle était surchargée pour accepter seulement 1 paramètre dans le cas où les deux types sont les mêmes ... un peu de creusage montré aucune preuve de cela, donc je l'ai modifié pour indiquer explicitement que les deux first et second sont int s.

+1

La définition dans la norme ne fournit pas un type par défaut pour le second type, vous devez donc fournir explicitement les deux types. –

23

La chose stockée dans un conteneur de la bibliothèque standard doit être affectable et peut être copiée - les tableaux ne le sont pas. Votre meilleur pari est de créer une liste de std :: vector. Vous pouvez également placer le tableau dans une structure:

struct A { 
    int array[2]; 
}; 

std::list <A> alist; 
+0

Comment voulez-vous pousser sur le des tableaux sur 'alist'? – JFA

7

Ceci est une bonne situation pour utiliser boost::array au lieu de tableaux de type C "classiques". Cela devrait fonctionner:

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

Je vous suggère d'utiliser std :: pair pour stocker les valeurs dans ce cas. Il est situé dans
<utility>.

Vous pouvez stocker des pointeurs sur les tableaux de la liste, mais vous devrez alors gérer toute la gestion de la mémoire. L'utilisation de la paire est beaucoup plus simple si les paires de valeurs sont tout ce dont vous avez besoin.

1

À partir de 11 C++, nous pouvons le faire avec le std::array standard:

#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 << ' '; 
} 

ou

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

etc. au silence un avertissement clang.

Sortie:

3 4 5 6 1 2 
1

Avec C++ 11 il y a un ::std::array wrapper disponible qui peut être utilisé avec des conteneurs standards comme celui-ci:

#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