Добавление массива в вектор

значения, разделенные запятыми в mysql, являются Нарушением 1-го NF

2
задан archity 13 July 2018 в 13:13
поделиться

3 ответа

Забудьте, что int[3] называет тип. C не ведут себя как разумные значения. Массивы называются std::array<type, count>.

#include <vector>
#include <array>

int main()
{
  std::vector<std::array<int, 3>> matchVector;

  std::array<int, 3> msmTemp;

  msmTemp[0] = 1;
  msmTemp[1] = 2;
  msmTemp[2] = 3;
  matchVector.push_back(msmTemp);
  msmTemp[0] = 4;
  msmTemp[1] = 7;
  msmTemp[2] = 0;
  matchVector.push_back(msmTemp);

  for(auto & arr : matchVector)
  {
    for(auto i : arr)
    {
      std::cout << i <<", ";
    }
    std::cout<<"\n";
  }

  return 0;
}
2
ответ дан Caleth 17 August 2018 в 12:46
поделиться
  • 1
    Первая строка в основной функции определяет вектор, который будет содержать значения массива типов, которые, в свою очередь, будут иметь тип int размера 3, является ли моя интерпретация правильной? – archity 13 July 2018 в 13:32
  • 2
    @archity std::array не является, по сути, типом. std::array<int, 3> - это тип, представляющий собой массив из 3 int s – Caleth 13 July 2018 в 13:33
  • 3
    @archity Вы читаете matchVector как "вектор массива из 3-х целых чисел" – Caleth 13 July 2018 в 13:34
  • 4
    Кроме того, как я могу разбить этот оператор на 2 части, инициализировать и присваивать, чтобы я мог использовать его для любой другой переменной, а не для размера 3? Особенно, если я хочу определить его внутри класса. – archity 13 July 2018 в 14:06
  • 5
    Чтобы использовать std::array, вы должны иметь постоянную времени компиляции для счета. Если у вас его нет, используйте std::vector – Caleth 13 July 2018 в 14:08

Другие ответы уже объясняют, как исправить ваш код. Я думаю, что также полезно объяснить, почему ваш код ведет себя так:

Здесь вы сообщаете компилятору создать std::vector, который содержит указатели на int:

std::vector<int*> matchVector;

Здесь вы сообщаете своему компилятору выделить некоторое пространство в стеке, которое соответствует 3-м целям:

int msmTemp[3];

Здесь вы сообщаете компилятору записать значения 1, 2 и 3 в память ранее выделенные:

msmTemp[0] = 1;
msmTemp[1] = 2;
msmTemp[2] = 3;

Здесь вы сообщаете своему компилятору взять адрес этого выделенного пространства, обрабатывать его как указатель и передавать его на push_back. Это называется распадом массива :

matchVector.push_back(msmTemp);

Теперь ваш matchVector содержит 1 элемент, который является указателем на адрес памяти в вашем стеке, который был выделен для хранения 3 ints.

Здесь вы сообщаете компилятору записать значения 4, 7 и 0 в ранее выделенной памяти. Обратите внимание, что это все тот же блок памяти, что и раньше:

msmTemp[0] = 4;
msmTemp[1] = 7;
msmTemp[2] = 0;

Здесь вы говорите своему компилятору, чтобы он снова взял адрес выделенного пространства, обработайте его как указатель и передайте его в push_back:

matchVector.push_back(msmTemp);

Таким образом, matchVector теперь содержит 2 одинаковых значения, каждый из которых является указателем на одно и то же место памяти. В частности, место памяти, которое вы в последний раз написали 4, 7 и 0 в.

1
ответ дан Max Vollmer 17 August 2018 в 12:46
поделиться
  • 1
    Это действительно хорошее объяснение исходному коду. Большое вам спасибо за это. – archity 13 July 2018 в 13:41

A int* является указателем на целое число.

int[3] представляет собой массив из 3 целых чисел.

Массив из 3 целых чисел «распадается» при падении шапки к указателю на первый элемент.

Когда вы делаете push_back(msmTemp), вы нажимаете указатель на первый элемент msmTemp в vector.

Указатели на C ++ не владеют тем, на что указывают. Вектор afte двух push_backs содержит два указателя, оба они относятся к одному и тому же массиву msmTemp.

Когда вы позже перебираете вектор, вы получаете по очереди два указателя. Каждый указывает на msmTemp.

Затем вы используете [] для индексации этих указателей. Когда у вас есть указатель на первый элемент массива, вы можете использовать [] для доступа к другим элементам массива. [0] - это первый элемент, [1] второй и т. д.

Итак, вы смотрите на 3 элемента в msmTemp (к счастью, оно имеет 3) и смотрите на них дважды, потому что у вас есть два указатели в него в вектор.

Вы можете вставлять такие элементы:

std::vector<int> matchVector;
int msmTemp[3];
msmTemp[0]={1};
msmTemp[1]={2};
msmTemp[2]={3};
matchVector.insert( matchVector.end(), std::begin(msmTemp), std::end(msmTemp) );

и т. д. Это заканчивается вектором, содержащим 6 элементов, а не два массива.

Если вам нужны массивы в качестве значений, которые вам нужны std::array:

std::vector< std::array<int,3> > matchVector;
std::array<int, 3> msmTemp;

, а затем ваш код работает как написанный , std::array - это тип библиотеки, который действует как сырой массив, но у него нет проблем с распадом на указатель для необработанного массива.

4
ответ дан Yakk - Adam Nevraumont 17 August 2018 в 12:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: