Пожалуйста, не используйте вложенные векторы , если размер вашего хранилища известен заранее , т. Е. Есть особая причина почему, например, первый индекс должен иметь размер 6 и никогда не изменится. Просто используйте простой массив. Еще лучше, используйте boost::array
. Таким образом, вы получаете все преимущества наличия простого массива (экономьте огромные объемы пространства при переходе в многомерное пространство) и преимущества создания реального объекта.
Пожалуйста, не используйте вложенные векторы , если ваше хранилище должно быть прямоугольным , т.е. вы можете изменить размер одного или нескольких измерений, но каждая "строка" должна быть такой же длины в какой-то момент. Используйте boost::multi_array
. Таким образом, вы документируете «это хранилище прямоугольное», сохраняете огромное количество места и при этом получаете возможность изменять размеры, преимущества наличия реального объекта и т. Д.
Суть std::vector
в том, что он (а) предназначен для изменения размера и (б) не заботится о его содержимом, если они имеют правильный тип. Это означает, что если у вас есть vector<vector<int> >
, то все «векторы строк» должны хранить свою собственную отдельную бухгалтерскую информацию о том, как долго они хранятся - даже если вы хотите, чтобы они имели одинаковую длину. Это также означает, что все они управляют отдельными выделениями памяти, что снижает производительность (поведение кэша) и тратит еще больше места из-за перераспределения std::vector
. boost::multi_array
разработан с учетом того, что вы, возможно, захотите изменить его размер, но не будете постоянно изменять его, добавляя элементы (строки, для 2-мерного массива / граней, для 3-мерного массива / и т. Д.) конец. std::vector
предназначен для (потенциально) бесполезного использования пространства, чтобы обеспечить медленную работу. boost::multi_array
предназначен для экономии места и аккуратной организации всего в памяти.
Сказано :
Да, вам нужно что-то сделать, прежде чем индексировать вектор. std::vector
не будет волшебным образом вызывать появление индексов, потому что вы хотите что-то там хранить. Однако с этим легко справиться:
Вы можете по умолчанию инициализировать вектор с соответствующим количеством нулей, а затем заменить их с помощью конструктора (size_t n, const T& value = T())
. То есть
std::vector<int> foo(10); // makes a vector of 10 ints, each of which is 0
потому что int, созданный по умолчанию, имеет значение 0.
В вашем случае нам нужно указать размер каждого измерения, создав подвекторы соответствующего размера и разрешив конструктору скопировать их. Это выглядит так:
typedef vector<float> d1;
typedef vector<d1> d2;
typedef vector<d2> d3;
typedef vector<d3> d4;
d4 result(2, d3(7, d2(480, d1(31))));
То есть безымянный d1
имеет размер 31, который используется для инициализации по умолчанию d2
, который используется для инициализации по умолчанию d3
, который используется для инициализации result
.
Есть и другие подходы, но они гораздо более неуклюжи, если вы просто хотите, чтобы началось множество нулей. Если вы собираетесь прочитать весь набор данных из файла, то:
Вы можете использовать .push_back()
для добавления к вектору. Сделайте пустой d1
непосредственно перед самым внутренним циклом, в котором вы неоднократно .push_back()
заполняете его. Сразу после цикла вы .push_back()
получаете результат на d2
, который вы создали непосредственно перед самым внутренним циклом, и т. Д.
Вы можете предварительно изменить размер вектора с помощью .resize()
, а затем индексировать его как обычно (вплоть до суммы, до которой вы изменили размер).