Как мне подтолкнуть векторы по ссылке? - PullRequest
0 голосов
/ 31 мая 2018

Этот код ниже не работает, потому что я возвращаю векторы a и b к вектору вектора, а затем изменяю векторы a и b.Я хочу изменить векторы a и b, чтобы вектор-вектор подвергался таким же модификациям.Как мне это сделать?

#include <iostream>
#include <vector>

int main()
{
std::vector<std::vector<int>>vector;
std::vector<int>a;
std::vector<int>b;
vector.push_back(a);
vector.push_back(b);
for (int i = 1; i <= 10; i++)
    a.push_back(i);
for (int i = 11; i <= 20; i++)
    b.push_back(i);
std::cout << vector[1][0];
std::cin.get();
}

Ответы [ 4 ]

0 голосов
/ 31 мая 2018

Если вы заранее знаете количество векторов, вы можете сделать это следующим образом:

std::vector<std::vector<int>> v(2);
std::vector<int> &a = v[0];
std::vector<int> &b = v[1];
...
0 голосов
/ 31 мая 2018

Вы можете использовать std::reference_wrapper (начиная с C ++ 11).

std::reference_wrapper - это шаблон класса, который оборачивает ссылку в копируемый, назначаемый объект.Он часто используется в качестве механизма для хранения ссылок внутри стандартных контейнеров (например, std::vector), которые обычно не могут хранить ссылки.

например,

std::vector<std::reference_wrapper<std::vector<int>>> v;
std::vector<int> a;
std::vector<int> b;
v.push_back(a);
v.push_back(b);
for (int i = 1; i <= 10; i++)
    a.push_back(i);
for (int i = 11; i <= 20; i++)
    b.push_back(i);
std::cout << v[1].get()[0]; //11

LIVE

Обратите внимание, что если vector имеет более длительный срок службы, чем a и b, то при уничтожении a и b ссылки, хранящиеся в vector, становятся висящими.

0 голосов
/ 31 мая 2018

Основная проблема заключается в том, что push_back копирует свой параметр в конец вектора.Чтобы изменить объект в векторе, вам нужно получить ссылку на него.Один из подходов:

std::vector< std::vector<int> > my_vector;
my_vector.reserve(2);  // Going over the allocation invalidates references

my_vector.push_back( std::vector<int>() );
std::vector<int> & a = my_vector.back();

my_vector.push_back( std::vector<int>() );
std::vector<int> & b = my_vector.back();

(я изменил имя переменной, потому что использование «вектора» в качестве имени переменной может привести к путанице.)

Если вы можете использовать C ++ 17есть способ уменьшить количество строк кода, используя emplace_back.

0 голосов
/ 31 мая 2018

Create v (vector не является подходящим именем, поскольку оно используется совместно с библиотекой и приводит к путанице в коде), чтобы быть vector из vector указателей (поскольку вектор ссылок не являетсявозможный ):

std::vector<std::vector<int> *> v; //declare as vec of vec pointers
...
v.push_back(&a); //push_back addresses of a and b
v.push_back(&b);
...
std::cout << v.at(1)->at(0) //dereference and call at on the inner vec

Обратите внимание, что это может быть опасно, если a или b выйдет из области видимости до v, поскольку это оставит вас с висящими указателями,беспорядок неопределенного поведения и убийства, отнимающие много времени.

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