Благодаря Ивану Стоеву я начал изучать AutoMapper.Collection , который действительно является расширением, которое я надеялся найти. После реализации мои списки обновляются так, как я хотел. Конфигурация проста в моем использовании, так как мне нужно только указать Id моих объектов.
Моя начальная конфигурация изменена на:
using AutoMapper;
using AutoMapper.EquivalencyExpression;
[....]
public void ConfigureServices(IServiceCollection services)
{
services.AddAutoMapper(cfg => {
cfg.AddCollectionMappers();
});
}
[....]
И мой профиль отображения:
CreateMap().ReverseMap()
.ForMember(m => m.Id, opt => opt.Ignore());
CreateMap().ReverseMap()
.EqualityComparison((sir, si) => sir.Id == si.Id);
Да, при стирании итератора тот итератор получает так называемое сингулярное значение, что означает, что он больше не принадлежит никакому контейнеру. Вы не можете увеличить, постепенно уменьшить или считать его/запись в него больше. Корректный способ сделать тот цикл:
for(map<T, S*>::iterator it = T2pS.begin(); it != T2pS.end(); T2pS.erase(it++)) {
// wilhelmtell in the comments is right: no need to check for NULL.
// delete of a NULL pointer is a no-op.
if(it->second != NULL) {
delete it->second;
it->second = NULL;
}
}
Для контейнеров, которые могли делать недействительным другие итераторы, когда Вы стираете один итератор, erase
возвращает следующий допустимый итератор. Затем Вы делаете это с
it = T2pS.erase(it)
Это - то, как это работает на std::vector
и std::deque
, но не для std::map
или std::set
.
Я думаю, изменяете ли Вы набор, Вы делаете недействительным свой итератор. Вы не можете полагаться на поведение, как Вы узнали.
for (i = v.begin(); i != v.end(); ) {
//...
if (erase_required) {
i = v.erase(i);
} else {
++i;
}
}
После вызова erase
на итераторе в a std::map
, это делается недействительным. Это означает, что Вы не можете использовать его. Попытка использовать его (например, путем постепенного увеличения его) недопустима и может заставить что-либо происходить (включая катастрофический отказ). Для a std::map
, вызов erase
на итераторе не делает недействительным никакой другой итератор так (например), после этого вызова, (пока it
не был T2pS.end()
), это будет допустимо:
T2pS.erase( it++ );
Конечно, при использовании этого подхода Вы не захотите безусловно увеличивать it
в для цикла.
Для этого примера, тем не менее, почему беспокойство для стирания в для цикла? Почему не только называют T2pS.clear () в конце цикла.
С другой стороны, похоже, что у Вас есть необработанный указатель 'справа' карты, но карта, кажется, владеет резким для возражения. В этом случае, почему бы не сделать вещь справа от карты своего рода интеллектуальным указателем, таким как станд.:: tr1:: shared_ptr?
[Кстати, я не вижу шаблонных параметров к map
. У Вас есть typedef'ed определенное инстанцирование std::map
как map
в локальном пространстве имен?]