2013-05-05 1 views
3

Я хотел пообщаться с std::array, чтобы увидеть, насколько он отличается от std::vector. До сих пор я нашел только одно существенное различие.std :: array vs std :: vector тонкая разница

Sentence sentence = { "Hello", "from", "GCC", __VERSION__, "!" }; 
std::array<std::string, 10> a; 
std::copy(sentence.begin(), sentence.end(), a.begin()); 

int i = 0; 
for (const auto& e : a) 
{ 
    i++; 
    std::cout << e << std::endl; 
} 
std::cout << i << std::endl; 

// outputs 10 

i = 0; 
for (const auto& e : sentence) 
{ 
    i++; 
    std::cout << e << std::endl; 
} 
std::cout << i << std::endl; 

// outputs 5 

for (int i = 0; i < a.size(); i++) 
    std::cout << i << " " << a[i] << std::endl; 

// outputs 0 Hello 
// ... 
//   4 ! 
//   5-9 is blank 

for (int i = 0; i < sentence.size(); i++) 
    std::cout << i << " " << sentence[i] << std::endl; 

// outputs 0 Hello 
// ... 
//   4 ! 
// stops here 


// The following outputs the same as above 
i = 0; 

for (auto it = a.begin(); it != a.end(); it++) 
{ 
    std::cout << i << " " << *it << std::endl; 
    i++; 
} 
std::cout << i << std::endl; 
i = 0; 
for (auto it = sentence.begin(); it != sentence.end(); it++) 
{ 
    std::cout << i << " " << *it << std::endl; 
    i++; 
} 
std::cout << i << std::endl; 

Так от того, что я могу видеть, std::array 's size и max_size является излишним, но std::vector' s size и capacity могут быть разными или одинаковыми. Это даже подтверждается по этой цитате:

Размер и максимальный размер объекта массива всегда совпадают.

Почему у std::array есть избыточные функции? Что еще более важно, считаете ли вы, что размер std::array не обязательно совпадает с размером std::vector, потому что вектор имеет емкость? Кроме того, означает ли это, что std::array s являются безопасными (то есть, у них есть интеллектуальное управление указателями, например, векторы?)

+1

Последние предложения заставляют меня думать, что у вас может быть некоторое замешательство в том, что такое 'std :: array'; возможно, посмотрите [здесь] (http://stackoverflow.com/questions/4424579/stdvector-versus-stdarray-in-c/4424658#4424658) для быстрого сравнения. –

+0

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

+6

Разница между 'std :: array' и' std: : vector' является FAR от тонкого –

ответ

2

capacity в vector - максимальная вместимость vector .., которая может быть или не быть такой же, как и ее size. size - текущее количество элементов в vector.

По соображениям производительности, если вы знаете максимальный размер вектора заранее (или имеете догадку), вы можете предварительно определить емкость вектора (а не использовать его значение по умолчанию). Это может значительно повысить производительность вашего кода, так как вам не придется перераспределять на каждой итерации (когда вы добавляете элементы).

http://www.cplusplus.com/reference/vector/vector/capacity/

5

Чтобы сделать его совместимым с другими контейнерами.

Таким образом, вы можете иметь функцию шаблона, которая берет любую коллекцию, и быть уверенным, что она будет работать одинаково независимо от того, является ли она std::vector или std::array.

1

Чтобы немного расширить, по субъекту std::array следует очень близко к реальной конструкции массива, таких как char[], в котором максимальный размер массива является размер массива. Это связано с тем, что массив можно представить как имеющий неизменный размер. Это размер, который нельзя изменить, кроме полного перераспределения памяти. В отличие от std::vector, который может быть установлен как capacity, и размер, который может быть от 0 до capacity, однако, как только он пройдет, значение capacity означает, что каждый новый элемент приведет к полному отдыху и распределению базового массива внутри vector.

2

Более важное различие состоит в том, что std::vector имеет функцию resize, тогда как std::array нет.

Размер экземпляра std::array (как и обычного массива) фиксируется при его создании (фактически его размер должен быть известен во время компиляции и быть постоянным выражением). Однако экземпляр std::vector может быть изменен после его создания во время выполнения.

Далее std::arrays различных размеров - разные типы, в то время как std::vectors разных размеров одного типа.

Единственная причина для использования std::array над std::vector состоит в том, что std::array использует меньше места и быстрее. A std::vector необходимо сохранить свой размер и указатель на хранилище резервных копий, которое может иметь дополнительное дополнение, позволяющее изменять размер. A std::array выделяется на месте (без косвенного указателя), а его функция size также известна статически, поэтому вызов std::array.size() будет скомпилирован в константу (это фактически функция constexpr).

1

Как вы отметили, std::array всегда одного размера. size() == capacity(). Это означает, что при создании std::array<T, 5> вы получаете пять вызовов до T по умолчанию. А std::vector<T>, с другой стороны, не будет создавать по умолчанию любые элементы. Вызов reserve(5) по вектору все равно не приведет к созданию каких-либо элементов.

Ни у std::array, ни у std::vector нет «умного управления указателями», по крайней мере, так, как я о них думаю. Оба они предоставляют типы итераторов, а также функции, такие как begin/end/rbegin/rend, которые позволяют перемещаться по элементам в контейнере. Когда люди говорят «умный указатель», я думаю о shared_ptr/unique_ptr/auto_ptr/etc.

В общем, std::array хранится в стеке, а std::vector выделяет хранилище в куче. В высокопроизводительных приложениях это большое преимущество для std::array. Выделение памяти в куче может быть в 100 или 1000 раз медленнее, чем использование стека, особенно в многопоточных приложениях.