Андрей Александреску убивает итераторы
Автор: Глеб Лебедев
В своё время Александреску произвёл много шума своей книгой «Современное проектирование на С++», в которой подробно описал такие вещи, как реализацию списков типов через шаблоны С++ и использование этого и других подходов для реализации ряда шаблонов проектирования.
На сайте boostcon.com опубликован доклад Андрея. В этот раз он покушается на основу STL — итераторы. Но, в отличие от многих критиков, которые только лишь ругают существующее положение дел, Александреску предлагает альтернативное решение. Увлекательное чтение для фанатов С++ доступно по этому адресу.
Видео для тех, кто предпочитает один раз увидеть:
16 сентября 2009
Категории: C++, STL, итераторы
Права на документ принадлежат автору, указывайте ссылку при цитировании
Обновление: 21 сентября 2009
| Phoenics | Участник | www | 21 сен. 2009 | 11:42 | #1 |
|---|
| Iskander | Постоялец | www | 21 сен. 2009 | 13:43 | #3 |
|---|
| kvakvs | Участник | www | 21 сен. 2009 | 13:46 | #4 |
|---|
Последняя правка: 21 сен. 2009 13:47
| Phoenics | Участник | www | 21 сен. 2009 | 14:27 | #5 |
|---|
В кратце автор перечисляет ряд недостатков итераторов и предлагает шире использовать range-ы. Так же он поясняет ряд преимуществ которые можно с этого получить. Мне например понравилась возможность связывать ранжи в списки, и возможность создавать бесконечные ранжи. В общем любопытно. Что такое сами range-ы и как они реализованы я пока не разбирался и не искал информацию по этому поводу, но думаю что это что-то типа итератора хранящего либо имеющего доступ к информации обо всех элементах в виде упорядоченного множества, благодаря чему появляются возможности не только ходить от одного элемента к другому но и делить/сливать эти множества, использовать вместо элементов функции, например для получения случайного значения или создания нового объекта, возможности накладывать фильтры на добавляемые/извлекаемые из рэнджа значения, возможность произвольно менять праивла обхода, например сделать рэндж зацикленным или нет, выбирать элементы в случайном порядке, ходить вперёд и назад без создания реверсивных итераторов, обходить деревья вглубь и т.п. возможности.
Так же среди преимуществ он отмечает более простой синтаксис, и то что рэнж не зависит например от типа контейнера, а только от типа элементов на которые он ссылается. Т.о. можно использовать рэнжи от разных контейнеров с одинаковыми элементами единообразно, например связывать их в списки, сделать так что бы какой-нибудь алгоритм например получал на вход рэнж одного типа контейнера а результаты складывал в рэнж другого типа контейнера.
Последняя правка: 21 сен. 2009 14:33
| Chipmunk | Постоялец | www | 21 сен. 2009 | 15:04 | #6 |
|---|
| Iskander | Постоялец | www | 21 сен. 2009 | 15:28 | #8 |
|---|
> типа итератора хранящего либо имеющего доступ к информации обо всех элементах в
> виде упорядоченного множества
То есть range это получается такой интерфейс контейнера? Или это что-то типа 2 iterators in 1? ))
| RPGman | Участник | www | 21 сен. 2009 | 15:45 | #9 |
|---|
> Или это что-то типа 2 iterators in 1? ))
Не. Там сама идея, что никому не нужен поштучный итератор. Если думать in general, то самый general случай - операции над группой объектов.
Нутро range не должно никого интересовать.
| Ghost2 | Постоялец | www | 21 сен. 2009 | 16:47 | #10 |
|---|
> Если да - то надо уже сейчас проектировать с этим "in mind"...
Проектировать что?
| Iskander | Постоялец | www | 21 сен. 2009 | 16:50 | #11 |
|---|
> Если думать in general, то самый general случай - операции над группой
> объектов.
То есть range - это такое математическое множество объектов данного итератора, удовлетворяющее каким-то условиям?
Только вот пример с find я не очень хорошо понял. В примере с итераторами find возвращает итератор из контейнера, который указывает на найденный элемент. Тут все просто и понятно.
В примере с range мы возвращаем "the range starting with the found element (if any), empty if not found". А где будет заканчиваться этот range? Он будет до конца контейнера? Или я ошибаюсь? Что потом делать дальше с этим ренджем тоже не очень понял.
Вот пример. Я передаю в find функтор для сравнения элементов контейнера, чтобы вызвать метод у элемента(ов) который удовлетворяет условию. Вот я получил range из find. Я буду делать что-то типа range.front().myMethod()? Или как? Тогда чем отличается от обычного итератора?
Как я понял, range "непрерывен", то есть нельзя получить как в linq список объектов удовлетворяющих данному условию типа
var range = container.Select(s => s.value == 1);
и затем foreach(r in range){r.myMethod()};
и мне нужно делать что-то вроде
range = container.all();
while(!range.empty){
range = find(range, value);
range.front().myMethod();
}
Я прав?
Или я все таки могу получить range содержащий только нужные элементы? Другими словами, какова концепция range - это ПРОИЗВОЛЬНОЕ множество, или множество от-до?
Ну или как вариант, может я вообще не понял о чем идет речь? ))
| Phoenics | Участник | www | 21 сен. 2009 | 17:08 | #12 |
|---|
> Как я понял, range "непрерывен", то есть нельзя получить как в linq список
> объектов удовлетворяющих данному условию типа
Такую хрень как я понял как раз можно будет сделать через фильтры, т.е. метод Select как бы создаст не обычный ранж а с установленнмы фильтром, как-то так
Последняя правка: 21 сен. 2009 17:09
| Iskander | Постоялец | www | 21 сен. 2009 | 17:15 | #13 |
|---|
> Такую хрень как я понял как раз можно будет сделать через фильтры, т.е. метод
> Select как бы создаст не обычный ранж а с установленнмы фильтром, как-то так
А вот это уже интересно. Дай ссылку, где про такое можно почитать, а?
| Phoenics | Участник | www | 21 сен. 2009 | 17:17 | #14 |
|---|
> В примере с range мы возвращаем "the range starting with the found element (if
> any), empty if not found". А где будет заканчиваться этот range? Он будет до
> конца контейнера? Или я ошибаюсь? Что потом делать дальше с этим ренджем тоже
> не очень понял.
насколько я понял -да, он будет от найденного элемента до конца контейнера, и в этом есть рациональное зерно на мой взгляд, допустим нам надо найти не один а группу объектов удовлетворящих условию, тогда у нас поидее для find-а есть два варинта либо мы возвращам range с объектами удовлетворящими условию, либо как у Александреску рэнж от найденного элемента до последнего.
В первом случае всё понятно, во втором мы забираем найденный объект через pop_front() и суём этот же ранж опять в find, и поиск начнётся с элемента следующего за найденным.
/ Форум / Программирование игр / Общее
Для определения, можете ли вы оставлять сообщения, необходимо войти в систему под своим логином.