В C ++ 20 мы получаем библиотеку Ranges. Я еще не рассматривал это подробно, но я подозреваю, что здесь могут помочь поддиапазоны или представления.
Pre C ++ 20
В C ++ (до сих пор) мы часто не передавайте напрямую список (или другой контейнер), а скорее пару итераторов. Взгляните на библиотеку <algorithm>
: такие функции, как std::sort
, не принимают ссылку на контейнер - вместо этого они принимают итератор first
и итератор last
.
Важно: last
указывает не на последний элемент, а на одно место за ним - то же, что даст вам std::list::end()
. Это означает, что когда first == last
у вас есть «пустой список»
В мире, предшествующем C ++ 20, вы обычно пишете свой код таким же образом. Одним из преимуществ этого является то, что если у вас есть пара итераторов first
и last
, то (до first != last
) *first
- это car
, а пара std::next(first)
и last
это cdr
. Итак:
(defun sum (list)
(if (null list)
0
(+ (car list) (sum (cdr list)))))
становится чем-то вроде
template <class ForwardIter>
int sum(ForwardIter first, ForwardIter last) {
return (first == last)
? 0
: (*first) + sum(std::next(first), last);
}
(я знаю, что некоторые люди не согласятся с тем, как я отформатировал этот условный оператор на нескольких строках - но я хотел отразить Lisp стиль.)