STL算法如何识别它在哪种容器上运行?
例如,sort
接受迭代器作为参数
它如何知道它要分类的容器类型?
答案 0 :(得分:6)
它没有:-)这就是迭代器的重点 - 对它们起作用的算法不需要知道任何有关底层容器的信息,反之亦然。
那怎么办?好吧,迭代器本身有一组well-known properties。例如,'随机访问'迭代器允许任何算法通过常量访问迭代器中的元素偏移量:
std::vector<int> vec = { 1, 2, 3, 4 };
assert(*(vec.begin() + 2) == 3);
对于排序,迭代器需要支持随机访问(为了以任意顺序访问第一个和最终迭代器之间的所有元素),并且它们需要是可写的(为了分配或以其他方式交换值) ),也称为&#39;输出&#39;迭代器。
输出迭代器与输入(只读)的示例:
std::vector<int> vec = { 1, 2, 3, 4 };
*vec.begin() = 9;
assert(vec[0] == 9);
*vec.cbegin() = 10; // Does not compile -- cbegin() yields a const iterator
// that is 'random-access', but not 'output'
答案 1 :(得分:3)
它不需要知道容器的类型,只需要知道迭代器的类型。
答案 2 :(得分:1)
如前所述,STL使用迭代器而不是容器。它使用称为“标签调度”的技术来推断出适当的算法风格。
例如,STL有一个函数“advance”,它在给定n个位置的情况下移动给它
template<class IteratorType,
class IntegerDiffType> inline
void advance(IteratorType& it, IntegerDiffType n)
对于双向迭代器,它必须应用++或 - 多次;对于随机访问迭代器,它可以立即跳转。此函数用于std :: binary_search,std :: lower_bound和其他一些算法。
在内部,它使用迭代器类型特征来选择策略:
template<class IteratorType,
class IntegerDiffType>
void advance(IteratorType& it, IntegerDiffType n)
{
typedef typename iterator_traits<IteratorType>::category category;
advance_impl(it, n, category());
}
当然,STL必须实现重载的“impl”函数:
template<class IteratorType,
class IntegerDiffType>
void advance(IteratorType& it, IntegerDiffType n, bidirectional_iterator_tag)
{ // increment iterator by offset, bidirectional iterators
for (; 0 < n; --n)
++it;
for (; n < 0; ++n)
--it;
}
template<class IteratorType,
class IntegerDiffType>
void advance(IteratorType& it, IntegerDiffType n, random_access_iterator_tag)
{ // increment iterator by offset, random-access iterators
it += n;
}