2012-01-08 4 views

ответ

92

Используйте 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 a (5,10);' '' 'означает' пространство для 5 'int' и инициализирует их с 10. Но как ваши x, x + ... работают? Вы можете объяснить? – UnKnown

11

Указатели могут быть использованы, как и любые другие итераторы:

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

В реальной жизни вы можете абстрагироваться от размера массива, например, используя 'const size_t X_SIZE = 3;' для обозначения размера массива или вычисления его из sizeof. Я пропустил эту часть для удобства чтения. –

77

Лично я очень нравится подход 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 }); 
+1

копирует массив или просто указывает на него? Я заинтересован в производительности –

+1

'std :: vector ' всегда владеет объектами 'T'. Это имеет два значения: при вставке объекта в вектор они копируются и размещаются в памяти. Для разумно малых объектов, например. последовательности коротких строк, коллокация является основным усилением производительности. Если ваши объекты большие и дорогие для копирования, вы можете захотеть сохранить указатели [как-то управляемые ресурсами] для объектов. Какой подход более эффективен, зависит от объектов, но у вас есть выбор. –

+0

, так что, если я хочу связать C++ и c-библиотеки и скопировать из c-массива в вектор и обратно, нет способа уплатить штраф в 2 копии?(я использую собственную библиотеку и gsl) –

4

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

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 

+0

«вместо того, чтобы заставлять все в векторе спрашивать, как вы можете преобразовать тест для работы с итераторами вместо конкретного контейнера». Почему это лучше? – aquirdturtle

+0

@aquirdturtle, потому что теперь, вместо поддержки только векторов, вы поддерживаете списки и массивы и форсируете контейнеры и преобразуете итераторы и диапазоны и ... – Flexo

Смежные вопросы