2013-11-11 5 views
0

Это может быть элементарный вопрос .. У меня есть класс, который выглядит следующим образом:Инициализация размер станд :: вектор

class Foo { 

    private: 

    vector<MyStructure> data; 

    public: 

    void read(const cv::FileNode& node) { 
     // read data from file 

     cv::FileNode n = node["MyStructure"]; 
     cv::FileNodeIterator it = n.begin(), it_end = n.end(); 
     for (int i = 0; it != it_end; ++it, ++i) { 
      *it >> data[i]; // there's a problem here. 
     } 
    } 

} 

Обратите внимание, что it является итератор, который указывает на MyStructure элементов в контейнере n. Вот моя проблема. Я не знаю размер vector<MyStructure> data заранее (когда я конструирую объект). Поэтому я просто не могу просто назначить *it >> data[i]. Этот код компилируется, но он будет раздавлен с ошибкой времени выполнения. Как я могу это исправить? Решение должно быть эффективным, если это возможно (то есть, следует избегать создания слишком большого количества объектов MyStructure).

+3

Um. Я не знаю 'cv' от Adam, но если он фактически содержит эквиваленты MyStructure как разыменованный результат разыменования FileNodeIterator, то почему бы не' std :: copy (n.begin(), n.end(), std :: back_inserter (данные)); '? – WhozCraig

+0

@WhozCraig Я попробовал ваше предложение с помощью 'std :: copy (n.begin(), n.end(), std :: back_inserter (data)) ;, но он не компилируется, к сожалению. – Alexey

+0

Да, у меня было ощущение, что это не может выглядеть так, как используется итератор (как источник извлечения, который представляет собой интересную абстракцию сам по себе). Это сделало бы жизнь намного легче, если бы она просто позволила простой eval. Ах. хорошо./ – WhozCraig

ответ

4
MyStructure temp; 
*it >> temp; 
data.push_back(std::move(temp)); 

Это позволяет избежать слишком большого количества копий объектов MyStructure. Он делает достаточно копии.

Если n является контейнером, который имеет функцию в size член, то сделать это первым:

data.reserve(n.size()); 
+0

Хорошая идея! Однако у меня нет компилятора C++ 11. – Alexey

+0

+1 У меня есть плюс 1 это только для местных знаний о cv. Разделяемые итераторы 'FileNodeIterator' разделяли действительно поддержку синтаксиса оператора извлечения? Это интересно. Мне нужно проверить этот комплект. – WhozCraig

+1

@Alex: Затем отпустите 'std :: move'. –

1

Может быть:

std::deque<int> accumulate; 
for(...) accumulate.push_back(...); 
// Getting a continuous vector 
std::vector result(accumulate.begin(), accumulate.end()): 
Смежные вопросы