在STL源码中如何理解这个模板的用法?

How to understand the usage of this template in STL source code?

我目前正在查看SGI STL的源代码,具体是距离的算法。

正如我所看到的,为了最大限度地提高效率,SGI 使用了很多内联模板来最大限度地减少 运行 时间。但是我真的不明白一件事。

对于距离算法,SGI定义了一个模板:

template <class Iterator>
inline typename iterator_traits<Iterator>::iterator_category
iterator_category(const Iterator&){
  typedef typename iterator_traits<Iterator>::iterator_category category;
  return category();
}

然后定义算法距离的public接口如

template <class Iterator>
inline iterator_traits<Iterator>::iterator_category
distance(InputIterator first, InputIterator last)
{
  typedef typename iterator_traits<InputIterator>::iterator_category category;
  return __distance(first, last, category());
}

在你对我的知识做出所有判断之前,我想说我认为了解STL的设计模式并且我了解每一行的含义,我的意思是语法。

但是据我所知,我只是不知道为什么SGI没有实现像

这样的算法距离
template <class Iterator>
inline iterator_traits<Iterator>::iterator_category
distance(InputIterator first, InputIterator last)
{
  return __distance(first, last, iterator_category<InputIterator>(first));
}

据我所知,函数调用会消耗一定的时间,但这里iterator_category是内联函数,在大多数主流编译器中与宏具有相同的效果。

使用 iterator_category() 的唯一不足可能是编译器由于传递常量引用而生成的临时对象。

我说的对吗?或者有什么我还没有认识的天才设计模式,有空告诉我!

在实现中使用 iterator_category<InputIterator>(first) 可能会被自定义迭代器的 ADL 劫持。

namespace HiJack
{
class MyIter{/*..*/};

template <class T> // would be not templated with call like iterator_category(first)
auto iterator_category(const MyIer&){ /*..*/ }
}

您可能认为 __distance__distance(first, last, category()); 中是一样的,但是 names with __ are reserved 不能被普通用户使用。

但完全合格的调用将解决这个问题(假设命名空间 sgi):

template <class Iterator>
inline iterator_traits<Iterator>::iterator_category
distance(InputIterator first, InputIterator last)
{
  return __distance(first, last, ::sgi::iterator_category<InputIterator>(first));
}