2017-02-21 26 views
0

Я использую std::mismatch, чтобы проверить, являются ли два вектора структур одинаковыми. Обычно в моей программе это не так, но в исключительных случаях это может случиться. В documentation я нахожу следующее:return value std :: несоответствие для равных векторов

«Если элементы по сравнению в обеих последовательностях все совпадают, то функция возвращает пару с первым набором для last1 и второй набор к элементу в том же относительном положении в секунду последовательность."

Однако, если я создаю два вектора, которые полностью равны, std :: mismatch не возвращает значение. Небольшой пример того, что я пытаюсь сделать:

#include <vector> 
#include <algorithm> 
#include <utility> 

struct structwithnumber { 
    int id; 
}; 

bool compare_structs (structwithnumber* struct1, structwithnumber* struct2) { 
    return struct1->id == struct2->id; 
}; 

bool compare_structvectors(std::vector<structwithnumber*> v1, std::vector<structwithnumber*> v2) { 
    if (v1.size() != v2.size()) 
    { 
     return false; 
    } 
    std::pair<std::vector<structwithnumber*>::iterator, std::vector<structwithnumber*>::iterator> mypair; 
    mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs); 
    return (compare_structs(*mypair.first, *mypair.second)); 
} 

void simple_example() { 
    structwithnumber* struct1 = new structwithnumber(); 
    structwithnumber* struct2 = new structwithnumber(); 
    struct1->id = 1; 
    struct2->id = 2; 
    std::vector<structwithnumber*> v1; 
    std::vector<structwithnumber*> v2; 
    v1.push_back(struct1); 
    v1.push_back(struct2); 
    v2.push_back(struct1); 
    v2.push_back(struct2); 
    compare_structvectors(v1, v2); 
} 

Когда я запускаю этот код в визуальной студии 15 я получаю ошибку на линии:

return (compare_structs(*mypair.first, *mypair.second)); 

О дальнейшем исследовании выясняется, mypair остатков пустой после несоответствия. Из документации, хотя я бы вернул последнее значение каждого вектора. Не понял ли я, как будет вести себя несоответствие, если будет представлено 2 последовательности, в которых все элементы совпадают?

+2

«Я получаю сообщение об ошибке» - не могли бы вы поделиться с аудиторией природой этой ошибки? (Скопируйте и вставьте из окна вывода.) – molbdnilo

+1

И [здесь] (http://en.cppreference.com/w/cpp/algorithm/mismatch) является более надежным эталонным сайтом. – molbdnilo

ответ

3

std::mismatch, в случае, если все соответствует, возвращает (t минимум один) итератор конца. Вы не можете разыгрывать его, как вы делаете, в compare_structs(*mypair.first, *mypair.second).

Код должен проверить для случая следующим образом:

mypair = std::mismatch(v1.begin(), v1.end(), v2.begin(), compare_structs); 

if(mypair.first == v1.end()) { 
    // No mismatch, do something sensible 
} else { 
    return (compare_structs(*mypair.first, *mypair.second)); 
} 
+0

Спасибо. Я изменю его на: mypair = std :: mismatch (v1.begin(), v1.end(), v2.begin(), compare_structs); возвращение (mypair.first == v1.end()); Поскольку второе утверждение всегда будет ложным. – MJV

0

Однако, если я создаю два вектора, которые полностью равны, станд :: несовпадение не возвращает значение

Разумеется, он должен вернуть что-то.

При дальнейших расследованиях выясняется, что mypair остается пустым после несоответствия.

Что это значит? Как mypair пусто? Это пара, у нее было ровно два члена, когда он был создан, и у него по-прежнему есть ровно два члена после вызова mismatch.

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

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

const bool v1_mismatch = (mypair.first != v1.end()); 
const bool v2_mismatch = (mypair.second != v2.end()); 
const bool identical = !(v1_mismatch || v2_mismatch); 

if (v1_mismatch && v2_mismatch) { 
    // this is the only case where you can dereference both 
    return compare_structs(*mypair.first, *mypair.second); 
} 
// otherwise you can dereference at most one iterator, 
// and if v1,v2 are identical, you can't dereference either 
+0

вы, вероятно, имеете в виду '||' там – Ap31

+0

Да, я был в двух умах о том, сколько деталей нужно положить в последний бит ... – Useless