Доступ к вектору как к массиву [] внутри функции - PullRequest
0 голосов
/ 01 марта 2012

Я хочу получить доступ к вектору в функции «манипулировать вектором» ниже так же, как я получаю доступ к массиву с вектором [i], а не с вектором -> в (i) в приведенном ниже коде.Я попытался передать вектор напрямую, а не указатель, как это можно сделать с массивами.Но это, кажется, портит программу.Есть идеи, как этого достичь?Я новичок в использовании библиотеки std, так как у меня есть опыт работы с C.

#include <vector>
#include <iostream>
#define vectorsize 5
struct st_test {
    int ii;
    float dd;
};

void manipulatevector(std::vector<struct st_test> *test) {
    test->resize(vectorsize);

    for(int i=0;i<vectorsize;i++) {
        test->at(i).dd = i*0.4f;
        test->at(i).ii = i;
    }
}

void manipulatearray(struct st_test test[vectorsize]) {
    for(int i=0;i<vectorsize;i++) {
        test[i].dd = i*0.4f;
        test[i].ii = i;
    }
}

void main() {
    std::vector<struct st_test> test1;
    manipulatevector(&test1);

    struct st_test test2[vectorsize];
    manipulatearray(test2);

    std::cout << "Vector" << std::endl;
    for(int i=0;i<vectorsize;i++) {
        std::cout << test1.at(i).dd << std::endl;
    }

    std::cout << "Array" << std::endl;
    for(int i=0;i<vectorsize;i++) {
        std::cout << test2[i].dd << std::endl;
    }
}

Ответы [ 6 ]

7 голосов
/ 01 марта 2012

Вы пытались передать вектор в качестве ссылки?

void manipulatevector(std::vector<struct st_test> &test) {
    test.resize(vectorsize);

    for(int i=0;i<vectorsize;i++) {
        test[i].dd = i*0.4f;
        test[i].ii = i;
    }
}

и

std::vector<struct st_test> test1;
manipulatevector(test1);
2 голосов
/ 01 марта 2012

Вы можете просто использовать (*test)[i] вместо test->at(i).

На самом деле это не то же самое поведение (at против operator[]), но вы, вероятно, уже знаете об этом.

1 голос
/ 01 марта 2012

Здесь есть разные варианты. Вы можете передать вектор по ссылке, которая является самой простой и понятной в коде:

 void function( std::vector<type>& v )

Теперь в некоторых магазинах руководство по стилю требует, чтобы, если вы собираетесь изменить аргумент, вы передаете его по указателю, поскольку это делает его явным в месте вызова. В этом случае есть разные варианты звонить operator[]:

 void function( std::vector<type> *v ){
    (*v)[0] = ....                     // dereference first
    v->operator[](0) = ....            // explicitly cal the operator
    std::vector<type>& vr =*v;
    vr[0] = ....                       // create reference and use that

Первые два эквивалентны, с первым, возможно, легче читать. Второй эквивалентен первому в том, что он разыменовывает указатель, а затем обращается к оператору, но вы явно присваиваете ссылку для ссылки, поэтому ее можно повторно использовать в функции без необходимости разыменования при любом использовании. Хотя это технически создает дополнительную переменную, компилятор, скорее всего, оптимизирует ссылку.

1 голос
/ 01 марта 2012

Изменить подпись void manipulatevector(std::vector<struct st_test> *test) на void manipulatevector(std::vector<struct st_test>& test).Тогда вы можете использовать operator[] на векторе.

1 голос
/ 01 марта 2012

Вы можете передать vector по ссылке и использовать оператор []:

void manipulatevector(std::vector<struct st_test>& test) {
    test.resize(vectorsize);

    for(int i=0;i<vectorsize;i++) {
        test[i].dd = i*0.4f;
        test[i].ii = i;
    }
}

Когда вы передали vector напрямую, я предполагаю, что вы передали его по значению:

void manipulatevector(std::vector<struct st_test> test) {

, что означало, что любые изменения, сделанные внутри manipulatevector(), не будут видны вызывающей стороне. Это будет означать:

for(int i=0;i<vectorsize;i++) {
    std::cout << test1.at(i).dd << std::endl;
}

выдаст ошибку std::out_of_range, начиная с test.at(i), так как test1 будет иметь не vectorsize элементов, а ноль элементов. Поскольку в main() нет обработки исключений, это привело бы к сбою программы.

1 голос
/ 01 марта 2012

Передайте его как указатель вместо указателя.

void manipulatevector(std::vector<struct st_test> &test) {

Затем вы используете . вместо ->, и можно использовать такие вещи, как перегруженный оператор [].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...