Мне нужно удалить элементы разных stl и форсировать контейнеры с помощью итератора. Иногда мне также нужно сделать это с помощью reverse_iterator, поэтому я хотел бы обернуть это в общую функцию (установить).Общая функция стирания
В соответствии с этим: Iterator invalidation rules в основном это возможно.
То, что я получил до сих пор это:
template<class T, bool T_IterReturned = helpers::EraseReturnsIterator<T>::value>
struct EraseImpl
{
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
static iterator erase(list& container, iterator it) {
return container.erase(it);
}
static const_iterator erase(list& container, const_iterator it) {
return container.erase(it);
}
};
template<class T>
struct EraseImpl<T, false>
{
// This one gets used for e.g. std::set whos erase does not return
// an iterator until C++11
typedef typename T::iterator iterator;
typedef typename T::const_iterator const_iterator;
static iterator erase(list& container, iterator it) {
container.erase(it++);
return it;
}
static const_iterator erase(list& container, const_iterator it) {
container.erase(it++);
return it;
}
};
template<typename T>
inline typename T::iterator erase(T& container, typename T::iterator it)
{
return detail::EraseImpl<T>::erase(container, it);
}
template<typename T>
inline typename T::reverse_iterator erase(T& container, typename T::reverse_iterator it)
{
typename T::reverse_iterator tmp = it;
return typename T::reverse_iterator(erase(container, (++tmp).base()));
}
Это должно работать в большинстве случаев, но, например, вектор-подобный контейнер, который не возвращает итератор, нарушит это. Наборы не делают недействительными любые другие итераторы -> ok для использования следующего итератора. Для векторов мне нужно будет сохранить предыдущий итератор (если есть) и вернуть его. Для дека (и аналогичного) без возврата итератора это не будет работать вообще. Я не хочу использовать EraseImpl для всех известных контейнеров, например, это потребовало бы, чтобы я включил все их заголовки, которых я хочу избежать.
Есть ли что-нибудь, что я могу, чтобы избежать его специализации для всех типов? Конечно, я могу создать черту с перечислением типа {Use_Next, Use_Prev} и оставить его неспециализированным для контейнеров, недействительных на всех итераторах. Но опять же: я не хочу включать все возможные заголовки.
Вам не нужно, чтобы включить все заголовки, опережающее объявление достаточно для признаков. – Jarod42
@ Jarod42: Вы не можете форматировать объявления стандартных типов библиотеки. Вот почему есть специальный ''. Однако это единственный такой заголовок. –
MSalters
Я подозреваю, что нет общего решения. Как вы будете иметь дело с контейнером, который недействителен _all_ iterators на 'erase'? Не то, что надуманно; векторный контейнер, который сжимается, может это сделать. (Перераспределение на меньший блок) – MSalters