Решаю небольшую задачку на тему словарей. Писал подульно, чтобы было можно сразу найти ошибки. Стал тестировать. В некоторых случаях выдаётся ошибка при вызове функии Print. Суть блока кода такая. Есть некий словарь словарей строк. В нём сейчас имеется некоторое количество элементов. На вход подаётся 2 строки, если первая строка есть, тогда создаётся временная переменная, в которой дабавляются все значения что были в этом элементе словаря. Затем удаляется этот элемент словаря и добавляется новый. Если в элементе словаря только 3 элемента или меньше, ошибка на первое добавление не срабатывает и всё выводится. При следующем добавлении, уже вылетает данная ошибка. Никак не пойму в чём дело...
void PrintSet(const set <string> &vectStr){
for(auto s: vectStr){
cout << s << endl;
}
}
void Print(const set<set<string>> &input){
for(auto s : input){
PrintSet(s);
}
}
//проверка есть ли элемент в словаре
bool FindInSet(const set<string> &setStr, const string &inputWord){
return setStr.count(inputWord);
}
//ADD word1 word2 — добавить в словарь пару синонимов (word1, word2)
void Add(set<set<string>> &input){
string word1, word2;
cin >> word1 >> word2;
set <string> words;
words.insert(word1);
words.insert(word2);
set <string> tmp;
bool check = false;// нет в словаре
for(auto s :input){
if(FindInSet(s, word1)){
tmp = s;
for(auto add : words){
tmp.insert(add);
}
input.erase(s);
input.insert(tmp);
check = true;
}
}
if(check == false){
input.insert(words);
}
}
int main() {
set<string> test = {"word", "words", "worde", "wow", "wwooccwoowo", "woccw", "wwccoowoowo"};
set<set <string>> test1;
test1.insert(test);
Add(test1);
//Add(test1);
cout << "end" <<endl;
Print(test1);
return 0;
}
for (auto s :input){
...
input.erase(s);
...
}
Вы удаляете из input
текущий итерируемый элемент контейнера. После этого поведение не определено. Все падает.
Range-based for цикл не является каким-то "волшебным" циклом, в котором можно делать что угодно. Range-based for - это не более чем "синтаксический сахар" для обыкновенного цикла с итератором. Этот итератор просто скрыт от ваших глаз. Уничтожив текущий элемент контейнера, вы сделали этот внутренний итератор невалидным. Далее все накрылось.
Не надо пользоваться range-based for в ситуациях, когда вы собираетесь модифицировать итерируемый контейнер.
P.S. У вас передача параметров везде выписана "по ссылке", чтобы избежать создания копий, а итерирование везде тупо делается по значению, создавая на каждой итерации никому не нужные копии "тяжелых" объектов. Раз уж вы умеете передавать аргументы по ссылке, то и итерировать, наверное, по ссылке должны уметь?
Виртуальный выделенный сервер (VDS) становится отличным выбором
Работающий код, функция testValue() возвращает копию значения:
Подскажите пожалуйста, чем отличается виртуальная функция от шаблонной функции?
Стоит задача считывать большие zip-архивы (от 500Мб и выше)