Как инициализировать вектор в C ++

Я хочу инициализировать вектор, как мы это делаем в случае массива.

Пример

int vv[2] = {12, 43};

Но когда я так делаю,

vector<int> v(2) = {34, 23};

OR

vector<int> v(2);
v = {0, 9};

выдает ошибку:

ожидаемое первичное выражение перед токеном "{"

И

ошибка: ожидалось ‘,’ или ‘;’ перед токеном ‘=’

соответственно.


person Md Faisal    schedule 18.01.2012    source источник
comment
comment
Вы должны включить поддержку C ++ 11 в своем компиляторе, например g++ -std=c++11 your_file.cc. Затем вы можете использовать конструктор списка инициализаторов потока (последний элемент в этой ссылке < / а>)   -  person    schedule 25.04.2013
comment
Не обман - другой вопрос, как это сделать со старым C ++, ответ WTF - как это сделать сейчас   -  person Martin Beckett    schedule 07.06.2013


Ответы (2)


С новым стандартом C ++ (могут потребоваться специальные флаги для включения в вашем компиляторе) вы можете просто сделать:

std::vector<int> v { 34,23 };
// or
// std::vector<int> v = { 34,23 };

Или даже:

std::vector<int> v(2);
v = { 34,23 };

В компиляторах, которые не поддерживают эту функцию (списки инициализаторов), вы можете эмулировать это с помощью массива:

int vv[2] = { 12,43 };
std::vector<int> v(&vv[0], &vv[0]+2);

Или, в случае присвоения существующему вектору:

int vv[2] = { 12,43 };
v.assign(&vv[0], &vv[0]+2);

Как предположил Джеймс Канце, более надежно иметь функции, которые дают вам начало и конец массива:

template <typename T, size_t N>
T* begin(T(&arr)[N]) { return &arr[0]; }
template <typename T, size_t N>
T* end(T(&arr)[N]) { return &arr[0]+N; }

И тогда вы можете сделать это, не повторяя размер повсюду:

int vv[] = { 12,43 };
std::vector<int> v(begin(vv), end(vv));
person R. Martinho Fernandes    schedule 18.01.2012
comment
Или просто: std :: vector ‹int› v (vv, vv + 2); - person Violet Giraffe; 18.01.2012
comment
Или более надежно: std::vector<int> v(begin(w), end(w);. begin и end являются стандартными для C ++ 11 (но тогда они вам не нужны), но в противном случае они должны быть в вашем наборе инструментов. - person James Kanze; 18.01.2012
comment
Я знаю, что это старый вопрос, но что именно вы здесь делаете: std::vector<int> v(&vv[0], &vv[0]+2);? Я вижу, что вы создаете вектор с местом для значений &vv[0] (который будет адресом памяти) и заполняете каждое пространство в векторе _3 _... Это будет использовать конструктор 2 на этой странице: en.cppreference.com/w/cpp/container/vector/vector без предоставления третий аргумент, который по умолчанию имеет значение Allocator (). Я знаю, что что-то упускаю. - person Mortimer McMire; 22.06.2013
comment
Я думаю, что std::vector<int> v(&vv[0], &vv[0]+2) на самом деле вызывает четвертый конструктор на этой странице. Конструктор может взять первый и последний элементы в диапазоне и создать вектор со всем, что находится между ними. Подсказка в том, что & приведет к адресам памяти. - person Prashant Kumar; 23.06.2013
comment
Что, если я хочу инициализировать массив в куче? - person qed; 16.07.2014
comment
@qed, как ты думаешь, что такое vector? - person R. Martinho Fernandes; 17.07.2014
comment
Не знаю, контейнер данных? - person qed; 17.07.2014
comment
А что за массив, как не за контейнер данных? - person R. Martinho Fernandes; 17.07.2014
comment
@qed Вектор - это массив в куче. - person R. Martinho Fernandes; 17.07.2014
comment
@ R.MartinhoFernandes Cool. Но почему мы никогда не удаляем вектор вручную? - person qed; 17.07.2014
comment
@ R.MartinhoFernandes А если я сделаю vector<int> b {1, 2}, будет ли b тогда указатель на вектор в куче? Это отличается от vector<int>* b = new vector<int>; b.push_back(1); b.push_back(2)? - person qed; 18.07.2014
comment
@qed Мы никогда не удаляем векторы вручную, потому что у них есть деструктор, который автоматически удаляет содержимое из кучи, и деструктор автоматически вызывается, когда вектор выходит за пределы области видимости. - person Buge; 04.08.2014
comment
@qed Во втором примере есть ошибка. Я думаю, вы имеете в виду b->push_back(1);. В первом примере b не указатель, это объект. Разница между этими двумя примерами заключается в том, где хранятся метаданные (размер и адрес основных данных). В первом примере размер и адрес основных данных хранятся в стеке. Во втором примере размер и адрес основных данных хранятся в куче. В обоих случаях основные данные хранятся в куче. - person Buge; 04.08.2014
comment
Какой стандарт вы имеете в виду под new - person Tik0; 21.07.2017

Вы также можете сделать это так:

template <typename T>
class make_vector {
public:
  typedef make_vector<T> my_type;
  my_type& operator<< (const T& val) {
    data_.push_back(val);
    return *this;
  }
  operator std::vector<T>() const {
    return data_;
  }
private:
  std::vector<T> data_;
};

И используйте это так:

std::vector<int> v = make_vector<int>() << 1 << 2 << 3;
person Viktor Sehr    schedule 18.01.2012
comment
Можно ли переместить data_ в v вместо вызова конструктора копирования? - person Per; 21.02.2018
comment
Привет, Пер! Я полагаю, вам это нравится (предупреждение, непроверено): operator std :: vector ‹T› && () {return std :: move (data_); } - person Viktor Sehr; 22.02.2018