c++ - 通用删除功能

标签 c++ stl iterator erase invalidation

我需要通过迭代器删除不同 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()));
}

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

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

最佳答案

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

默认为“Not-Allowed”,但也为具有删除功能的容器提供特化,返回一个迭代器。这是以通用方式完成的,因此仅检查此类函数的存在。如果找到,generic_erase 将使用它。如果不是,特征会询问用户专门的一个删除器对迭代器(next_iterator_valid、prev_iterator_valid、all_invalid)做了什么,然后 generic_erase 相应地进行操作。

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

关于c++ - 通用删除功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31819899/

相关文章:

c++ - 如何链接一个简单的 libssh 程序

c++ - 使用 sqrt() 和 pow() 函数的不同结果

java - 实现这样的迭代器?

具有动态项目大小的 C++ vector

c++ - 在具有动态路径C++的文件夹中写入文件

c++ - 基于堆栈缓冲区的STL分配器?

C++ 11 STL 列表 = 和 != op 未定义

c++ - 我如何知道 C++ 模板是容器还是类型?

python - 以可迭代作为参数的函数是否总是接受迭代器?

c++ - vector 迭代器不兼容