2009-05-05 15 views
12

Przy użyciu C++ i STL, czy ktoś wie, jak przechowywać tablice liczby całkowitej jako węzły na liście STL lub wektor? Mam nieznaną liczbę par liczb, które muszę przechowywać, a pochodząc z innych języków, myślałem, że będę używał jakiejś struktury danych typu listowego lub wektorowego ... ale mam pewne problemy. Jestem w 100% pewna, że ​​popełniam oczywisty błąd dla początkujących w C++ i że ktoś, kto rzeczywiście zna ten język, rzuci okiem na to, co próbuję zrobić i będzie w stanie mnie wyprostować.Jak przechowywać tablice na liście STL?

Oto, co próbowałem. Deklarując listę jak działa tak:

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

A potem mogę łatwo zrobić tablicę dwóch elementów, tak jak poniżej:

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

To kompiluje i działa dobrze. Jednak jak tylko próbuję dodać foo do mojej listy, tak jak poniżej:

my_list.push_back(foo); 

dostaję cały gnarly zestaw błędów kompilatora, z których żadna nie naprawdę zrozumieć (moje C++ - fu jest prawie nieistniejąca):

/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 

Więc ktoś ma pomysły co do tego, co robię źle tutaj? Wszelkie wskazówki (bez gry słów) byłyby najbardziej pomocne. Czy nie jest możliwe przechowywanie tablic na std :: list? Czy powinienem używać struct? Czy brakuje mi gdzieś numeru * lub &?

Odpowiedz

9

Nie można przechowywać tablic w kontenerach STL. Można użyć wektora wektorów lub somesuch dla ogólnego przypadku. W twoim konkretnym przypadku użyłbym wektora std :: pair, tak jak: std::vector<std::pair<int, int> >. std::pair to klasa, która ma dwóch członków, first i second, niezależnie od tego, jaki typ masz na to szablon.

Edytuj: Pierwotnie miałem to jako std::vector<std::pair<int> >, ale nie byłem pewien, czy był przeciążony, aby zaakceptować tylko 1 parametr w przypadku, gdy oba typy są takie same ... nie było na to kopania, żadnych dowodów na to, więc zmodyfikowałem go tak, aby jednoznacznie określał, że zarówno first, jak i first is.

+1

Definicja w standardzie nie zapewnia domyślnego typu dla drugiego typu, dlatego należy jawnie podać oba typy. –

23

Rzecz przechowywana w kontenerze biblioteki standardowej musi być możliwa do przypisania i kopiowania - tablice nie są ani. Najlepiej jest utworzyć listę std :: vector. Alternatywnie można zawrzeć tablicę w strukturze:

struct A { 
    int array[2]; 
}; 

std::list <A> alist; 
+0

Jak można naciskać na tablice na 'alist'? – JFA

7

Jest to dobra sytuacja w przypadku korzystania z boost::array zamiast "klasycznych" tablic w stylu C. To powinno działać:

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

Sugeruję użyć std :: pair do przechowywania wartości w tym przypadku. Znajduje się on pod numerem
<utility>.

Można przechowywać wskaźniki do tablic na liście, ale wtedy trzeba by zająć się wszystkimi zarządzaniem pamięcią. Używanie pary jest o wiele prostsze, gdy pary wartości są wszystkim, czego potrzebujesz.

1

Jak C++ 11, możemy to zrobić za pomocą standardowego 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 << ' '; 
} 

lub

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

itp uciszyć jakieś ostrzeżenie clang.

wyjściowa:

3 4 5 6 1 2 
1

z C++ 11 jest ::std::array wrapper dostępne, które mogą być stosowane w standardowych pojemnikach tak:

#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