2012-01-05 5 views
3

Давайте я имеюИнициализировать вектор структур

struct Vector { 

    float i,j,k; 
} 

Я хочу обнулить все элементы VEC объявленной ниже (I, J, K = 0)

std::vector <Vector> vec; 
vec.resize(num,0); 

Я не хочу использовать reserve(), а затем push_back() обнуляет один за другим. Другое дело, после успешной инициализации vec, я хочу, чтобы все члены vec были снова равны нулю после того, как они будут обработаны. Есть ли что-то вроде memset для векторов?

EDIT: Я сравнил все методы в Майк Сеймура и ответы XEO и в результате size_t size = vec.size(); vec.clear(); vec.resize(size); является самым быстрым, если они повторяются часто в цикле.

ответ

7

Это очень просто:

vec.resize(num); 

или отформатируйте ее с требуемым размером:

std::vector<Vector> vec(num); 

Как конструктор и resize заполнит новые элементы с объектами стоимостью инициализирован. Инициализированный по значению объект типа без конструктора по умолчанию (например, ваш Vector) будет иметь все числовые члены, инициализированные до нуля.

Чтобы сбросить все к нулю, либо

size_t size = vec.size(); 
vec.clear(); 
vec.resize(size); 

или:

std::fill(vec.begin(), vec.end(), Vector()); 

или менее эффективно, но с сильной гарантией исключения:

std::vector<Vector>(vec.size()).swap(vec); 
+0

Что касается реселлинга, какой из них быстрее, vec.clear ... или заполнить ...? – Shibli

+0

@Shibli: Они почти наверняка очень похожи по скорости. Если это важно для вас, вам придется их измерять. Если скорость действительно важна, вы можете обнаружить, что 'memset' немного быстрее (см. Ответ Xeo), но более опасный, поскольку он будет разбиваться неопределенными способами, если вы измените свой тип, чтобы он больше не был POD. Опять же, единственный способ сказать, действительно ли это быстрее - это измерить его. –

1

C++ способ настройки всех существующих элементов в 0:

std::fill(vec.begin(), vec.end(), 0); 

Или, в качестве альтернативы, для повторной инициализации до заданного размера:

vec.clear(); 
vec.resize(num, 0); 

Это не может быть столь же производительным, как memset, но достаточно хорош для 99% случаев.

+0

Должен ли я включать 0 в VEC .resize (num, 0)? Потому что Майк Сеймур этого не делал. – Shibli

+0

Он объясняет неявную инициализацию в своем ответе. Использование конструктора по умолчанию (без 0) является хорошим. – thiton

1

Вы можете просто использовать memset, так долго ваш Vector тип POD:

std::vector<Vector> v(num, 0); // inital fill 
// do stuff 
memset(&v[0], 0, sizeof(Vector) * v.size()); 

Хотя версия C++ будет с std::fill

#include <algorithm> 

std::fill(v.begin(), v.end(), 0); 
+0

@Mike: Ох, хорошая точка. Спасибо за напоминание. – Xeo

+0

Что происходит, если это версия или путь на C++? Что произойдет, если это по-другому? – Shibli

+0

@Shibli: 'std :: fill' будет работать для любого типа, который вы можете поместить в' vector'.'memset' действителен только для типов простых данных (POD); он будет разбит, если тип имеет конструкторы, деструкторы, виртуальные функции или другие осложнения. –