Я работаю над фрагментом кода C++, оставленным предшественником, и он, по-видимому, хранит vector<long int>
как vector<vector<long int>>
. Код компилируется и запускается, но я не понимаю почему. Вот функция, которая сохраняет.
void setPotentialParameters(const int& seed, const int& nMax, const double& lambdaStd, const int fieldNum, potentialPars& par)
{
gsl_rng * r = gsl_rng_alloc (gsl_rng_taus);
gsl_rng_set (r, seed);
par.nMaximum= nMax;
par.fNum= fieldNum;
for (int i=0; i<100; i++) gsl_ran_gaussian (r, lambdaStd);
int counter=0;
vector<long int> tempNs(fieldNum); //Defines tempNs as a vector<long int>
for (long int i=0; i< (-0.2+pow(2*nMax+1, fieldNum)); i++) {
findPartition(i, fieldNum, 2*nMax+1, tempNs );
for (int i = 0; i < tempNs.size(); i++) {
tempNs[i] -= nMax;
}
if (goodPartition(tempNs, nMax)) {
counter++;
par.lambdas.push_back(abs( gsl_ran_gaussian (r, lambdaStd)));
par.nVals.push_back(tempNs); //Stores tempNs in nVals
par.alphas.push_back(2*M_PI * gsl_rng_uniform (r));
};
};
};
И это структура, в которой хранится tempNs.
struct potentialPars{
int nMaximum;
int fNum;
vector<double> lambdas;
vector<vector<long int> > nVals; //Defines nVals as a vector<vector<long int>>
vector<double> alphas;
};
Я отметил три самые актуальные строки комментариями. tempNs имеет только один элемент (как видно из строки tempNs[i] -= nMax
), что соответствует его определению как vector<long int>
, но когда nVals вызывается в другом месте программы, он имеет два элемента, что также соответствует его определению как vector<vector<long int>>
. Это не кажется возможным. Несмотря на то, что tempNs модифицируется функцией findPartition, он все равно должен оставаться вектором длинных целых чисел. Что мне не хватает?
Не в виде, а в. У вас может быть сумка, в которой есть другие сумки.
tempNs
- это не то же самое, что nVals
. Элементы nVals
являются копиями tempN
.
vector<vector<long> >
имеет элементы типа vector<long>
. Метод push_back()
вектора копирует элемент в вектор. par.nValues
относится к типу vector<vector<long> >
, поэтому продвижение tempNS
- типа vector<long>
- вполне уместно.
vector<vector<long int> > nVals;
<- это определенный для приема векторов. Код помещает в него векторы с помощью nVals.push_back(tempN)
. tempN
- это вектор.
Спасибо за ответы, теперь это имеет смысл. Для подтверждения: предположим, что tempNs [5] = 2, и это третий вектор, который хранится в nVals. Означает ли это, что nVals [3] [5] = 2?
Нет, значит nVals[2][5] = 2
. Первый элемент вектора имеет нулевой индекс, а не единицу.
@Peter предлагает написать это как ответ, так как он решает мой вопрос =)
Нет проблем с использованием вектора длинных векторов. Это почти то же самое, что и использование двумерного массива, но вам не нужно знать размер во время компиляции или управлять выделением памяти.
Скомпилировать этот код нетрудно. Элементы вектора могут быть примитивами (int, float, double), указателями или другими объектами (например, вектором или вашими пользовательскими классами).
Ограничения на (первый) параметр типа std::vector
довольно слабые. Практически любой нереференсный тип может быть сохранен в std::vector
, включая std::vector
чего-то еще. Именно это и делает этот код.
Вы можете обернуть std::vector<long int>
в
struct partition {
std::vector<long int> indexes;
double lambda;
double alpha;
};
и замените potentialPars
на
struct potentialPartitions {
int nMaximum;
int fNum;
std::vector<partition> partitions;
};
что добавит ясности, но изменит способ доступа потребителя potentialPartitions
к этим значениям.
vector<vector<long> >
имеет элементы типа vector<long>
.
Метод vector
s push_back()
копирует элемент в вектор.
В коде, который вы показали, par.nValues
относится к типу vector<vector<long> >
, поэтому продвижение tempNS
, имеющего тип vector<long>
, вполне уместно.
используйте комментарии в коде, а не * перед кодом, так как * имеет какое-то значение в C++