C++ STL算法如何识别容器?

C++ STL算法如何识别容器?,c++,algorithm,stl,iterator,containers,C++,Algorithm,Stl,Iterator,Containers,STL算法如何识别它所操作的容器类型? 例如,sort接受迭代器作为参数。 它如何知道它必须对什么类型的容器进行排序?它不知道:-)这就是迭代器的全部意义——在迭代器上工作的算法不需要知道任何关于底层容器的信息,反之亦然 那么它是如何工作的呢?迭代器本身有一组特定的。例如,“随机访问”迭代器允许任何算法通过常数访问迭代器的元素偏移量: std::vector<int> vec = { 1, 2, 3, 4 }; assert(*(vec.begin() + 2) == 3); st

STL算法如何识别它所操作的容器类型?
例如,
sort
接受迭代器作为参数。
它如何知道它必须对什么类型的容器进行排序?

它不知道:-)这就是迭代器的全部意义——在迭代器上工作的算法不需要知道任何关于底层容器的信息,反之亦然

那么它是如何工作的呢?迭代器本身有一组特定的。例如,“随机访问”迭代器允许任何算法通过常数访问迭代器的元素偏移量:

std::vector<int> vec = { 1, 2, 3, 4 };
assert(*(vec.begin() + 2) == 3);
std::vector vec={1,2,3,4};
断言(*(vec.begin()+2)==3);
对于排序,迭代器需要支持随机访问(以便以任意顺序访问第一个迭代器和结束迭代器之间的所有元素),并且需要可写(以便分配或交换值),否则称为“输出”迭代器

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

std::vector vec={1,2,3,4};
*向量begin()=9;
断言(vec[0]==9);
*vec.cbegin()=10;//不编译--cbegin()生成常量迭代器
//这是“随机访问”,但不是“输出”

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

如前所述,STL使用迭代器,而不是容器。它使用被称为“标记分派”的技术来推断适当的算法风格

例如,STL有一个函数“advance”,它将给定的迭代器移动给定的n个位置

template<class IteratorType,
    class IntegerDiffType> inline
    void advance(IteratorType& it, IntegerDiffType n)
模板内联
void advance(IteratorType&it,IntegerDiffType n)
对于双向迭代器,它必须多次应用++或-;对于随机访问迭代器,它可以立即跳转。此函数用于std::binary_搜索、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());
}
模板
void advance(IteratorType&it,IntegerDiffType n)
{
typedef typename迭代器_traits::category;
高级应用程序(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;
} 
模板
void advance(迭代器类型&it,IntegerDiffType n,双向迭代器标记)
{//按偏移量递增迭代器,双向迭代器
对于(;0
根据迭代器的类型,排序是如何进行的?我又添加了一个相关的问题。@cppcoder:
std::swap()
交换两个任意的东西(它是为一般情况而模板化的,为速度而专门针对某些类型)
std::vector::swap
仅将一个向量的内容与另一个向量的内容交换。@cppcoder如果ti不清楚,向量的交换是一个非常有效的O(1)操作。@Cameron当存在
std::vector::swap
时,为什么
std::swap
存在?它有什么好处?我也不会说算法需要知道迭代器的类型。编译器需要知道迭代器的类型,以便使模板变成一个真正的函数(因为C++是静态类型的),但是算法本身并不关心。它只是盲目地假设迭代器支持它需要的操作,如果它不支持,你就会得到编译器错误。@Benjamin:是的,但是如果算法不能编译,除非你给它一个特定类型的迭代器,那么我认为隐式假设/耦合足够强,可以称为“关心”关于迭代器的类型:-)您的第二个问题应该在单独的线程中提出。下面的答案假设您已经知道模板和(模板参数推断的基础)是如何工作的,但您似乎不知道。基本上,
sort()
不是一个特定的函数,而是一个模板——可以通过在编译时替换某些内容(如容器或迭代器类型)来自动生成(无限)数量的函数。询问是否需要更多信息。
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;
}