Код хранит вектор как вектор <vector>, почему нет сообщения об ошибке?

Я работаю над фрагментом кода 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, он все равно должен оставаться вектором длинных целых чисел. Что мне не хватает?

используйте комментарии в коде, а не * перед кодом, так как * имеет какое-то значение в C++

Arkady Godlin 11.04.2018 12:17

Не в виде, а в. У вас может быть сумка, в которой есть другие сумки.

tempNs - это не то же самое, что nVals. Элементы nVals являются копиями tempN.
molbdnilo 11.04.2018 12:36

vector<vector<long> > имеет элементы типа vector<long>. Метод push_back() вектора копирует элемент в вектор. par.nValues относится к типу vector<vector<long> >, поэтому продвижение tempNS - типа vector<long> - вполне уместно.

Peter 11.04.2018 12:36
vector<vector<long int> > nVals; <- это определенный для приема векторов. Код помещает в него векторы с помощью nVals.push_back(tempN). tempN - это вектор.
Galik 11.04.2018 12:37

Спасибо за ответы, теперь это имеет смысл. Для подтверждения: предположим, что tempNs [5] = 2, и это третий вектор, который хранится в nVals. Означает ли это, что nVals [3] [5] = 2?

Allure 11.04.2018 12:54

Нет, значит nVals[2][5] = 2. Первый элемент вектора имеет нулевой индекс, а не единицу.

Peter 11.04.2018 13:03

@Peter предлагает написать это как ответ, так как он решает мой вопрос =)

Allure 11.04.2018 13:08
2
8
86
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Нет проблем с использованием вектора длинных векторов. Это почти то же самое, что и использование двумерного массива, но вам не нужно знать размер во время компиляции или управлять выделением памяти.

Скомпилировать этот код нетрудно. Элементы вектора могут быть примитивами (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>.

Метод vectors push_back() копирует элемент в вектор.

В коде, который вы показали, par.nValues относится к типу vector<vector<long> >, поэтому продвижение tempNS, имеющего тип vector<long>, вполне уместно.

Другие вопросы по теме