通用擦除功能

时间:2015-08-04 21:44:25

标签: c++ stl iterator erase invalidation

我需要通过迭代器擦除不同stl和boost容器的元素。有时候我也需要用reverse_iterator来做这个,所以我想把它包装成一个泛型函数(set)。

根据这个: 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()));
}

这适用于大多数情况,但例如一个不返回迭代器的类似矢量的容器会破坏它。集合不会使任何其他迭代器无效 - &gt;好的,可以使用next-iterator。对于向量,我需要存储前一个迭代器(如果有的话)并返回它。对于deque(和类似的)w / o迭代器返回,这根本不起作用。我不想为所有已知的容器实现EraseImpl,例如这需要我包含我想避免的所有标题。

有什么我可以避免为所有类型专门化吗?当然,我可以使用类似{Use_Next,Use_Prev}的枚举创建一个特征,并将其保留为非专用于使所有迭代器无效的容器。但同样:我不想包括所有可能的标题。

1 个答案:

答案 0 :(得分:0)

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

默认为“Not-Allowed”,但也为具有erase函数的容器提供特化,返回迭代器。这是以通用方式完成的,因此仅检查是否存在这样的函数。如果找到,generic_erase使用它。如果不是,特征会询问用户专用的一个擦除对迭代器做什么(next_iterator_valid,prev_iterator_valid,all_invalid)和generic_erase相应的行为。

这对该任务很有帮助:Check for function signature also for inherited functions