Как C ++ создает разные векторы при двумерной векторной инициализации? - PullRequest
1 голос
/ 14 апреля 2020

Я видел несколько мест ( например ), где можно инициализировать 2-мерный вектор следующим образом:

vector<vector<int> > vec(3, vector<int>(2, 0));

Я думаю, что этот код соответствует следующему

auto tmp = vector<int>(2, 0);
vector<vector<int> > vec(3, tmp);

Если я прав, то 3 элемента vec все ссылаются на одну и ту же ссылку. Что означает, что изменение vec[0][1] также изменяет vec[1][1].

Если я ошибаюсь, как C ++ делает инициализацию каждого элемента в vec другой ссылкой?

Ответы [ 2 ]

2 голосов
/ 14 апреля 2020

По умолчанию почти все контейнеры C ++ (включая std::vector) принимают свои аргументы копией, поэтому:

auto tmp = vector<int>(2, 0);
vector<vector<int> > vec(3, tmp);

Теперь вектор создает три копии 'tmp' совершенно не связаны друг с другом и хранят его внутри себя.

Обратите внимание, что то, что вы пытаетесь сделать, возможно , используя std::reference_wrapper, например: std::vector<std::reference_wrapper<std::vector<int>>>.

Пример:

#include <vector>
#include <functional>
#include <iostream>

int main()
{
    auto tmp = std::vector<int>(2, 0);
    std::vector<std::reference_wrapper<std::vector<int>>> a(3, std::ref(tmp));
    a[0].get()[0] = 2;
    a[1].get()[1] = 10;
    a[2].get()[0] = 30;
    std::cout << "'tmp' contains: ";
    for (auto const& elem : tmp)
        std::cout << elem << " ";
}

Вывод:
tmp содержит: 30 10

0 голосов
/ 14 апреля 2020

Из конструктора ссылка

3) Создает контейнер с количеством копий элементов со значением value.

Нет ссылок на tmp, только копии. Все отдельные векторы различны, и изменение одного не приведет к изменению любого другого.

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