Как хранить массивы в списке STL?
Используя С++ и STL, кто-нибудь знает, как хранить целые массивы в виде узлов в списке или векторе STL? У меня есть неизвестное количество пар чисел, которые мне нужно хранить, и, исходя из других языков, моя первая мысль заключалась в том, чтобы использовать какую-то структуру данных в виде списка или вектора... но я столкнулся с некоторыми проблемами. Я на 100% уверен, что я делаю очевидную ошибку С++ для начинающих, и что кто-то, кто действительно знает язык, возьмет один взгляд на то, что я пытаюсь сделать, и смогу установить меня прямо.
Итак, вот что я пробовал. Объявление такого списка работает:
stl::list<int[2]> my_list;
И тогда я могу легко создать двухэлементный массив, например:
int foo[2] = {1,2};
Это компилируется и работает отлично. Однако, как только я попытаюсь добавить foo
в свой список, вот так:
my_list.push_back(foo);
Я получаю целый gnarly набор ошибок компилятора, ни один из которых я действительно не понимаю (мой С++ - fu почти не существует):
/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
Итак, у кого-нибудь есть идеи относительно того, что я делаю неправильно здесь? Любые указатели (не предназначенные для каламбуров) были бы наиболее полезными. Невозможно ли хранить массивы в std:: list? Должен ли я использовать структуру? Я просто пропустил *
или &
где-нибудь?
Ответы
Ответ 1
Вы не можете хранить массивы в контейнерах STL. Вы бы использовали вектор векторов или, что то же самое, для общего случая. Для вашего конкретного случая я бы использовал вектор std:: pair, например: std::vector<std::pair<int, int> >
. std::pair
- это класс, который имеет два члена, first
и second
, любого типа, который вы его планируете.
Изменить: я изначально имел его как std::vector<std::pair<int> >
, но я не был уверен, что он был перегружен, чтобы принять только 1 параметр в том случае, если оба типа одинаковы... немного копания не появилось никаких доказательств этого, поэтому я изменил его, чтобы явно указать, что как first
, так и second
являются int
s.
Ответ 2
Вещь, хранящаяся в контейнере стандартной библиотеки, должна быть назначаемой и скопируемой - массивы тоже не являются. Лучше всего создать список std::vector. Кроме того, вы можете обернуть массив в struct:
struct A {
int array[2];
};
std::list <A> alist;
Ответ 3
Это хорошая ситуация для использования boost:: array вместо "классических" массивов C-стиля.
Это должно работать:
std::list<boost::array<int,2> > my_list;
boost::array<int,2> foo={{1,2}};
my_list.push_back(foo);
Ответ 4
Я предлагаю вам использовать std:: pair для хранения значений в этом случае. Он расположен в
<utility>
.
Вы можете сохранить указатели на массивы в списке, но тогда вам придется иметь дело со всем управлением памятью. Использование пары намного проще, если вам нужны пары значений.
Ответ 5
Как и в С++ 11, мы можем сделать это со стандартным 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 << ' ';
}
или
l.push_back({{1,2}});
и т.д.. чтобы заставить замолчать некоторые предупреждения о кланге.
Вывод:
3 4 5 6 1 2
Ответ 6
С С++ 11 существует ::std::array
обертка, которая может использоваться со стандартными контейнерами следующим образом:
#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);
}
Запустите этот код онлайн