Який найпростіший спосіб перетворити масив у вектор?


94

Який найпростіший спосіб перетворити масив у вектор?

void test(vector<int> _array)
{
  ...
}

int x[3]={1, 2, 3};
test(x); // Syntax error.

Я хочу найпростішим способом перетворити x з масиву int у вектор.

Відповіді:


140

Використовуйте vectorконструктор, який бере два ітератори, зауважте, що покажчики є дійсними ітераторами, і використовуйте неявне перетворення з масивів у покажчики:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + sizeof x / sizeof x[0]);
test(v);

або

test(std::vector<int>(x, x + sizeof x / sizeof x[0]));

де sizeof x / sizeof x[0]очевидно 3в цьому контексті; це загальний спосіб отримання кількості елементів у масиві. Зверніть увагу, що x + sizeof x / sizeof x[0]вказує на один елемент за останнім елементом.


1
Ви можете пояснити це, будь ласка? Я вже читав, що vector<int> a(5,10);означає make room for 5 int`, і ініціалізую їх 10. Але як працює ваш x, x + ...? ти можеш пояснити?
Асіф Муштак

1
@UnKnown замість вибору vector<int>::vector(size_type, int), він вибирає vector<int>::vector(int*, int*), що копіює діапазон, позначений цією парою покажчиків. Перше - це перевантаження (2), друге - перевантаження (4) тут
Калет

1
На c ++ 11 std :: instance краще, ніж метод sizeof. sizeof x / sizeof x[0] == std::extent<decltype(x)>::value
Ісаак Паскуаль

115

Особисто мені дуже подобається підхід C ++ 2011, оскільки він не вимагає sizeof()ні використання, ні пам’ятати про коригування меж масиву, якщо ви коли-небудь змінюєте межі масиву (і ви можете визначити відповідну функцію в C ++ 2003, якщо хочете, теж ):

#include <iterator>
#include <vector>
int x[] = { 1, 2, 3, 4, 5 };
std::vector<int> v(std::begin(x), std::end(x));

Очевидно, що з C ++ 2011 ви все одно можете використовувати списки ініціалізаторів:

std::vector<int> v({ 1, 2, 3, 4, 5 });

2
копіює масив або просто вказує на нього? я стурбований роботою
kirill_igum

2
std::vector<T>завжди володіє Tоб’єктами. Це має два наслідки: при вставці об'єкта у вектор вони копіюються і розміщуються в пам'яті. Для досить малих об’єктів, наприклад послідовностей коротких рядків, колокація є значним виграшем у продуктивності. Якщо ваші об’єкти є великими та дорогими для копіювання, ви можете заховати зберегти покажчики [якимось чином керованим ресурсом] на об’єкти. Який підхід є більш ефективним, залежить від об'єктів, але у вас є вибір.
Дітмар Кюль

тож, якщо я хочу взаємодіяти з бібліотеками c ++ та ac та скопіювати з c-масиву у вектор і назад, немає можливості сплатити штраф у розмірі 2 копій? (я використовую власну бібліотеку та gsl)
kirill_igum

16

Покажчики можна використовувати як будь-які інші ітератори:

int x[3] = {1, 2, 3};
std::vector<int> v(x, x + 3);
test(v)

2
У реальному житті вам може знадобитися абстрагувати розмір масиву, наприклад, використовуючи const size_t X_SIZE = 3;для позначення розміру масиву, або обчислюючи його за розміром. Я опустив цю частину заради читабельності.
Рафал Равіцький

11

Ви тут ставите неправильне питання - замість того, щоб змушувати все перетворюватися на вектор, запитайте, як ви можете перетворити тест на роботу з ітераторами замість конкретного контейнера. Ви також можете забезпечити перевантаження, щоб зберегти сумісність (і одночасно безкоштовно обробляти інші контейнери):

void test(const std::vector<int>& in) {
  // Iterate over vector and do whatever
}

стає:

template <typename Iterator>
void test(Iterator begin, const Iterator end) {
    // Iterate over range and do whatever
}

template <typename Container>
void test(const Container& in) {
    test(std::begin(in), std::end(in));
}

Що дозволяє вам:

int x[3]={1, 2, 3};
test(x); // Now correct

( Демонстрація Ideone )


"замість того, щоб змушувати все перетворюватися на вектор, запитайте, як ви можете перетворити тест на роботу з ітераторами замість конкретного контейнера." Чому це краще?
aquirdturtle 02

1
@aquirdturtle, тому що тепер, замість того, щоб підтримувати лише вектори, ви підтримуєте списки та масиви, а також підсилюєте контейнери та трансформуєте ітератори та діапазони та ....
Flexo

2
і вам не потрібно було копіювати дані
Гонки легкості на орбіті

2

Одним простим способом може бути використання assign()функції, яка заздалегідь визначена в vectorкласі.

напр

array[5]={1,2,3,4,5};

vector<int> v;
v.assign(array, array+5); // 5 is size of array.

2
Еквівалентно використанню ctor, про яке згадувалося в існуючих відповідях близько семи років тому. Нічого не додає ...
Гонки легкості на орбіті
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.