STL算法如何识别容器?

时间:2014-04-30 17:05:35

标签: c++ algorithm stl iterator containers

STL算法如何识别它在哪种容器上运行? 例如,sort接受迭代器作为参数 它如何知道它要分类的容器类型?

3 个答案:

答案 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;
}