通用擦除功能

Generic erase function

我需要通过迭代器擦除不同 stl 和 boost 容器的元素。有时我还需要用 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()));
}

这应该适用于大多数情况,但例如没有 return 迭代器的 vector-like 容器会破坏它。集合不会使任何其他迭代器无效 -> 可以使用 next-iterator。对于向量,我需要存储前一个迭代器(如果有的话)和 return 那个。对于双端队列(和类似的)w/o 迭代器 return 这根本不起作用。我不想为所有已知容器实现 EraseImpl,例如这将要求我包括他们所有我想避免的 headers。

我能做些什么来避免针对所有类型专门化它吗?当然,我可以用 {Use_Next, Use_Prev} 这样的枚举创建一个特征,并让它不专门用于使所有迭代器无效的容器。但同样:我不想包括所有可能的 headers.

我目前使用的解决方案是使用一个特征 class 可以专门用于每个容器 class。

默认为 "Not-Allowed",但也为具有擦除功能的容器提供专门化,即 returns 迭代器。这是以通用方式完成的,因此仅检查此类函数的存在。如果找到,generic_erase 将使用它。如果不是,特征会询问用户专门的一个擦除对迭代器(next_iterator_valid、prev_iterator_valid、all_invalid)和 generic_erase 的相应行为。

这对完成这项任务很有帮助: