IEnumerable в С++?

Я хотел бы знать, существует ли общий способ представления высокоуровневых спископодобных объектов в C++, отличный от использования итераторов STL. (под высокоуровневым я подразумеваю некоторые сложные объекты, скажем, ответ базы данных, а не низкоуровневый вектор). Вероятно, что-то похожее на IEnumerable в С#. Если вы видели какие-либо проекты, использующие это, не могли бы вы дать мне ссылку? Спасибо.

РЕДАКТИРОВАТЬ: Разъяснение, почему меня это интересует, а не часть вопроса. Как было сказано в комментариях, вот некоторый код, объясняющий важную разницу, которую я вижу между полиморфизмом во время компиляции и во время выполнения. Представьте, что у вас есть полиморфный тип времени компиляции, что в основном означает, что у вас есть два типа, которые имеют общую концепцию (не интерфейс). Если вы хотите применить алгоритм к этому полиморфному типу, он должен быть общим:

template<class iterator>
void myalgorithm(iterator iter) {...}

Но когда у вас есть полиморфный тип времени выполнения с интерфейсом, скажем, IMyIterator, вы можете написать на нем «обычные», необобщенные алгоритмы.

void myalgorithm(IMyIterator* iter) {...}

Большая разница в реализации этих двух функций заключается в разном уровне поддержки языка и IDE для работы с интерфейсами и универсальными типами. Другое дело, что не все так хорошо знакомы с программированием шаблонов, как, вероятно, вы. Наконец, второй случай позволяет скрыть реализацию, а первый — только заголовок. Поэтому, пожалуйста, не говорите мне, что между ними нет никакой разницы, если вы не можете показать мне, где я не прав.


person Roman L    schedule 01.02.2011    source источник
comment
Есть ли особая причина, по которой вы не любите итераторы STL? Или это просто из любопытства?   -  person templatetypedef    schedule 01.02.2011
comment
В управляемом C++ да (это тот же интерфейс, что и в C# и VB.Net). В стандартном C++ нет (и вам лучше использовать другой язык для обработки операций с базой данных).   -  person Zac Howland    schedule 01.02.2011
comment
@templatetypedef: Оба. Если вам действительно интересно, почему, посмотрите множество моих комментариев: stackoverflow.com/questions/4852658/polymorphic-iterators-in-c   -  person Roman L    schedule 01.02.2011
comment
Почему (не итераторы)? Это (современный) способ C++ для итерируемых контейнеров (даже C++0x для каждой конструкции использует их «внутри»!)   -  person eq-    schedule 01.02.2011
comment
Пример желаемого варианта использования, пожалуйста?   -  person John Dibling    schedule 01.02.2011
comment
@eq-, @John Dibling: Ну, я попытаюсь объяснить в нескольких словах. Основная причина в том, что я не хочу, чтобы меня заставляли и заставляли других здесь писать общие алгоритмы, которые были бы необходимы в случае общих итераторов, фильтров и т. д. Мне также не нужно запускать на них алгоритмы STL. Итераторы STL представляют собой концепцию очень низкого уровня (подобную указателю) и плохо обобщают (в отличие, например, от генераторов). Реализация итераторов STL - это боль (да, я знаю о boost.iterator). Поэтому я подумал, что если есть общая концепция высокого уровня, я мог бы ее использовать.   -  person Roman L    schedule 01.02.2011
comment
@7vies: Я могу согласиться только с указателем и генератором и с вытекающей из этого болью :) Языки более высокого уровня нас портят :p   -  person Matthieu M.    schedule 01.02.2011
comment
@7ives: я в замешательстве. Вы говорите, что не хотите писать обобщенную функциональность или использовать общий итератор, но вы спрашиваете о штуковине типа IEnumerable. IEnumerable настолько универсален, насколько это возможно. Является ли универсальность проблемой, которую вы пытаетесь решить?   -  person John Dibling    schedule 01.02.2011
comment
Некоторый код, иллюстрирующий то, что вы хотели бы сделать, поможет немного прояснить ваш вопрос.   -  person John Dibling    schedule 01.02.2011
comment
@John Dibling: IEnumerable, хотя и является универсальным типом, является интерфейсом. Объект, реализующий такой интерфейс, может обрабатываться обычным, необобщенным алгоритмом, даже если сам объект может быть полиморфным. Все это невозможно с полиморфизмом времени компиляции. Я не уверен, какой код я мог бы написать, чтобы проиллюстрировать эту идею.   -  person Roman L    schedule 01.02.2011
comment
@Matthieu M.: Вы не согласны с тем, что я заставляю остальных писать общие алгоритмы?   -  person Roman L    schedule 01.02.2011
comment
@7ives: Думаю, меня смущает ваше заявление о том, что это невозможно с полиморфизмом времени компиляции. Это утверждение ложно. Если бы вы могли опубликовать код, который показывает, что это правда, я мог бы быть вам больше полезен.   -  person John Dibling    schedule 01.02.2011
comment
@Джон Диблинг: Хорошо, я обновил вопрос, он более понятен?   -  person Roman L    schedule 01.02.2011
comment
@7vies: я люблю универсальное программирование (и в некоторой степени шаблоны), поэтому я могу признать ценность вашего аргумента, но я буду придерживаться использования шаблонов в своем коде, когда смогу. Между прочим, один из реальных аргументов против шаблонов заключается в том, что они требуют знания задействованных типов во время компиляции, что несовместимо с фабриками в целом.   -  person Matthieu M.    schedule 01.02.2011
comment
@7ives: В некоторой степени, но теперь вы сделали вопрос субъективным и аргументативным. тогда как раньше я надеялся, что это просто техническая проблема, которую мы могли бы решить.   -  person John Dibling    schedule 01.02.2011
comment
@Matthieu M.: Проблема в том, что это не только мой код, если бы это было так, я бы без колебаний использовал шаблоны :) Для меня фабрики — это всего лишь один пример, когда требуется настоящий полиморфизм во время выполнения, а их много. другие. И для меня это не только вопрос реального полиморфизма во время выполнения, я вижу и другие проблемы, некоторые из которых я упомянул.   -  person Roman L    schedule 01.02.2011
comment
@Джон Диблинг: Это уточнение, а не вопрос. Мой фактический вопрос перед частью EDIT и не является субъективным. Если бы вы могли волшебным образом решить вопросы, которые я упомянул о полиморфизме времени компиляции, я был бы счастлив.   -  person Roman L    schedule 01.02.2011
comment
@7ives: интересно, ты действительно спрашиваешь об отражении? en.wikipedia.org/wiki/Reflection_(computer_science)   -  person John Dibling    schedule 01.02.2011
comment
@John Dibling: Вау, совсем нет, но мне любопытно узнать, что заставило тебя так подумать. Я действительно не вижу связи между полиморфизмом компиляции/времени выполнения и отражением.   -  person Roman L    schedule 01.02.2011
comment
@7ives: я опубликую что-то, что может показаться бессвязным :)   -  person John Dibling    schedule 01.02.2011


Ответы (3)


Вы можете использовать SCARY-итераторы. База данных — это один из приведенных примеров того, где итерация SCARY преуспевает.

Однако IEnumerable<T> в C# на самом деле ничем не отличается от итерации STL, за исключением того, что задействованный полиморфизм применяется во время выполнения, а не во время компиляции. Не должно быть слишком сложно написать собственный полиморфизм времени выполнения поверх него.

person Puppy    schedule 01.02.2011
comment
Для меня разница огромная. Алгоритмы для полиморфных типов времени выполнения не обязательно должны быть универсальными, в то время как полиморфизм времени компиляции можно обрабатывать только с помощью универсальных алгоритмов. Это полностью меняет код, как будто он написан на каком-то другом языке. Так что это как минимум важно. P.S. Спасибо за ссылку, очень интересно. - person Roman L; 01.02.2011
comment
@7vies: Алгоритмы полиморфизма времени выполнения ничем не отличаются от алгоритмов полиморфизма времени компиляции: вы определяете интерфейс, а затем реализуете его. Независимо от того, определяете ли вы этот интерфейс как концепцию времени компиляции или как ABC времени выполнения, это не меняет того факта, что вы реализуете интерфейс. - person Puppy; 01.02.2011
comment
Хотел бы я, чтобы это было правдой... Но на практике полиморфизм времени компиляции гораздо сложнее реализовать, чем во время выполнения (один из простых примеров - использование списков типов и списка указателей на интерфейс). Еще одно отличие состоит в том, что полиморфизм времени выполнения позволяет полностью разделить интерфейс и реализацию, а полиморфизм времени компиляции — только заголовок. Так что я определенно не согласен, что нет никакой разницы :) - person Roman L; 01.02.2011
comment
Я обновил вопрос, указав более подробную информацию об этом, так как у меня было несколько подобных комментариев. - person Roman L; 01.02.2011
comment
Я прочитал газету, на которую вы дали ссылку, она мне все еще интересна, но не более того. Статья посвящена конкретному вопросу, касающемуся полиморфных итераторов и реализаций STL, но вряд ли является доказательством того, что итерация SCARY превосходна в какой-то области. - person Roman L; 02.02.2011

Одним из примеров альтернативы может быть в Qt4 представлены итераторы в стиле Java. :

QList<int> list;
...
QListIterator<int> i(list);
while (i.hasNext())
    sum += i.next();
person Georg Fritzsche    schedule 01.02.2011
comment
Это несправедливо, Qt - это Qt, а не C++ :) - person Roman L; 01.02.2011
comment
@Georg: Интересно, что я предпочитаю выполнять операции в другом порядке. Вместо того, чтобы иметь bool hasNext() const и T next(), я предпочел бы T get() const и bool next(), потому что я мог бы захотеть разыменовать элемент несколько раз. - person Matthieu M.; 01.02.2011
comment
@Matthieu M.: Вот как это делается в Java, я почти уверен, что у них были веские причины сделать это таким образом ... или они просто сделали это неправильно :) - person Roman L; 01.02.2011
comment
@7vies: интерфейс, который я предлагаю, на самом деле требует 3 метода, поскольку вы также добавили бы isValid в смесь, так что, возможно, целью было минимизировать количество методов (поскольку это несколько упрощает интерфейс). - person Matthieu M.; 01.02.2011
comment
@Matthieu M.: Наверное, я тоже об этом подумал. Между прочим, в последний раз, когда я думал о isValid, я нашел эту страницу и ссылки на ней довольно интересными (как общее обсуждение, я не занимаюсь Java) c2.com/cgi/wiki?IteratorSemanticsAreWrong, так что если вы не видели, это может быть вам интересно :) - person Roman L; 01.02.2011
comment
@Matthieu: Я согласен с этим подходом, комбинированный геттер / итерация - это то, к чему нужно привыкнуть. @7vies: Хорошо :D - person Georg Fritzsche; 02.02.2011

вы также можете увидеть Boost::FOR_EACH, это упрощает синтаксис итерации.

person DesignFirst    schedule 01.02.2011