Как понять использование этого шаблона в исходном коде STL? - PullRequest
0 голосов
/ 24 марта 2020

В настоящее время я просматриваю исходный код 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();
}

И затем он определил интерфейс publi c алгоритма расстояния, как

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 () может быть временный объект, сгенерированный компилятором из-за передачи по константной ссылке.

Я прав? Или есть какая-то гениальная модель дизайна, которую я еще не узнал, дайте мне знать!

1 Ответ

1 голос
/ 24 марта 2020

Использование 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());, но имен с __ зарезервированы и не могут использоваться обычным пользователем.

Но при полной квалификации вызов решит это (при условии пространства имен sgi):

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