2016-06-20 2 views
1

У меня примерно следующий код, который должен собрать уникальные показатели сегмента в uniques:Что случилось с std :: unique_copy (или моим использованием)?

vector<int> segments; 
    // segments vector is filled in here 
    // ... 
    sort(segments.begin(), segments.end()); 
    vector<int> uniques; 
    uniques.reserve(segments.size()); 
#ifdef USE_STD_UNIQUE_COPY 
    unique_copy(segments.begin(), segments.end(), uniques.begin()); 
#else 
    if(segments.size() > 0) 
     uniques.push_back(segments[ 0 ]); 
    for(size_t i = 1; i < segments.size(); ++i) 
    { 
     if(segments[ i ] != uniques.back()) 
      uniques.push_back(segments[ i ]); 
    } 
#endif 

Когда USE_STD_UNIQUE_COPY определен код не удается; когда он не определен, он работает так, как ожидалось. Вся часть работает на нескольких потоках, и я еще не отлаживал, как отличается результат std::unique_copy. Независимо от того, в соответствии с cppreference std::unique_copy (1), следует сделать именно то, что делает часть кода #else.

Таким образом, вопрос: что не так на этой картинке? У std::unique_copy есть ограничение, возможно, не потокобезопасное? Или, может быть, я неправильно читаю cppreference и неправильно его использую?

+6

's/uniques.begin()/back_inserter (uniques) /' –

+2

'reserve'! =' Resize'. поэтому ваш 'unique_copy' ошибочен, или вы должны использовать' back_inserter' – Jarod42

+0

Третий параметр должен быть 'output_iterator'. – Arunmu

ответ

3

Проблема в том, что вы пытаетесь скопировать недействительный диапазон назначения. По сути, ваш призыв к резервированию выделяет пространство, которое требуется вектору, но фактически не изменяет его размер. Таким образом, вы не можете напрямую копировать свои элементы. Ваш альтернативный код работает, потому что вызовы push_back расширяют размер вектора на 1 и добавляются к концу.

Как уже указывалось в комментариях, существует разумный способ использования unique_copy. Вы меняете его, чтобы использовать back_inserter для диапазона назначения.

unique_copy(segments.begin(), segments.end(), back_inserter(uniques)); 

back_inserter создает back_insert_iterator, который, при копировании, вызывает push_back на контейнере.

+0

Спасибо, сейчас работает. – Michael

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

  • Нет связанных вопросов^_^