STL具有可以在任意容器上运行的全局算法,只要它们支持该算法的基本要求即可。例如,某些算法可能要求容器具有随机访问迭代器,如向量而不是列表。
当容器具有比通用算法更快的方式时,它提供了一个具有相同名称的成员函数来实现相同的目标 - 就像提供自己的remove_if()
的列表一样,因为它可以删除元素只需在恒定时间内执行指针操作。
我的问题是 - 是否可以/建议专门化通用算法,以便它们自动调用容器的成员函数版本,从而提高效率?例如。在内部std::remove_if
调用list::remove_if
列表。这已经在STL中完成了吗?
答案 0 :(得分:4)
不在remove_if
的情况下,因为语义不同。 std::remove_if
实际上并没有从容器中删除任何东西,而list::remove_if
却没有,所以你绝对不希望前者调用后者。
你和实现都不能真正专门化容器的通用算法,因为算法是带迭代器的函数模板,容器本身是类模板,其迭代器类型取决于模板参数。因此,为了std::remove_if
专门针对list<T>::iterator
进行专门化,您需要remove_if
的部分专精,并且不存在部分专业化的问题。功能模板。
我不记得是否允许实现为特定迭代器类型重载算法,但即使不是“官方”算法也可以调用可能重载的函数,或者它可以使用可能部分专用的类。不幸的是,如果您编写了自己的容器,这些技术都没有帮助您,并且发现了一种方法来使标准算法特别有效。
假设您有一个带有随机访问迭代器的容器,但是您可以使用特别有效的排序技术来处理标准排序:也许是一个桶排序。然后,您可能会考虑将自由函数template <typename T> void sort(MyContainer<T>::iterator first, MyContainer<T>::iterator last)
放在与该类相同的命名空间中,并允许人们使用using std::sort; sort(it1, it2);
而不是std::sort(it1, it2);
来调用它。问题是,如果他们在通用代码中这样做,他们冒着其他人写一些其他容器类型的风险将会有一个名为sort
的函数甚至不对范围进行排序(英文单词“sort”的数量超过一个意思,毕竟)。所以基本上你不能通过一种方式对迭代器范围进行排序,从而提高用户定义容器的效率。
当代码中的差异仅取决于迭代器的类别时(例如std::distance
对于随机访问迭代器而言速度很快,否则慢),这是使用称为“迭代器标记分派”的东西完成的,并且这是不同容器之间明显的效率差异的最常见情况。
如果有任何剩余的情况适用于标准容器(折扣结果不同或效率只需要特定迭代器类别的情况),那就让我们拥有它们。
答案 1 :(得分:3)
这是不可能的 - 算法使用迭代器,迭代器不知道它们引用的容器对象。即使他们这样做了,也没有办法在编译时确定给定的迭代器范围是否指的是整个容器,所以不能仅通过专业化来完成;需要额外的运行时检查。
答案 2 :(得分:1)
执行此操作的唯一方法是为每个算法创建自己的包装器模板,使用容器而不是一对迭代器。然后,您可以为每个可以优化的容器类型专门设置包装器。不幸的是,这消除了标准算法的许多灵活性,并且通过一堆非标准调用来填充您的程序。
答案 3 :(得分:0)
您要找的不是专业化,而是重载。您可以提供算法的替代版本(不是,在法律上,在命名空间std
中),将容器作为参数而不是迭代器对,并调用STL挂件调用{{容器上有1}}和begin()
,或者做其他事情。当然,这种方法确实需要代码来调用您的函数而不是STL函数。
之前肯定已经完成了,所以你实际上可能会找到一组标题,从而省去了编写所有这些样板代码的工作。