繁体   English   中英

STL算法如何识别容器?

[英]How does an STL algorithm identify the container?

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

它不是:-)这就是迭代器的全部要点 - 对它们起作用的算法不需要了解底层容器的任何信息,反之亦然。

它是如何工作的呢? 好吧,迭代器本身具有一定的众所周知的属性 例如,'random-access'迭代器允许任何算法通过常量访问迭代器的元素偏移量:

std::vector<int> vec = { 1, 2, 3, 4 };
assert(*(vec.begin() + 2) == 3);

对于排序,迭代器需要支持随机访问(为了以任意顺序访问第一个和最终迭代器之间的所有元素),并且它们需要是可写的(为了分配或以其他方式交换值),否则称为“输出”迭代器。

输出迭代器与输入(只读)的示例:

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'

它不需要知道容器的类型,只需知道迭代器的类型即可。

如前所述,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;
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM