Итераторы C++, которые рассматривают вредными?

Хорошо, я нахожу способ реализовать это:

Требовать плагин электронной торговли:

ReactGA.ga("trackerGlobal.require", "ecommerce");

Чтобы добавить транзакцию:

ReactGA.ga(`${trackerName}.ecommerce:addTransaction`, {
  id: orderId,
  affiliation: "Affiliation",
  revenue: order.price
});
47
задан 8 revs, 6 users 38% 15 February 2016 в 18:58
поделиться

13 ответов

Сначала ответим на ваши вопросы:

  1. Нет. Фактически, я утверждал в другом месте , что итераторы являются наиболее важной / фундаментальной концепцией информатики. Я (в отличие от Андрея) также считаю, что итераторы интуитивны .
  2. Да, определенно, но это не должно вызывать удивления.
  3. Хмм. Глядя на Boost.Range и C ++ 0x - не так ли?

Большой вклад Андрея заключается в том, чтобы просто сказать: отбросьте концепцию итераторов в целом, рассматривайте диапазоны не просто как вспомогательную оболочку а скорее как основная конструкция. Другие языки уже сделали это (большая часть концепций Андрея просто повторяет .NET LINQ или итераторы Python), но все они предлагают только выходных диапазонов . Андрей рассуждает о разных типах диапазонов, во многом как обычные категории итераторов.

В этом свете странно, что он начинает с издевательства над произвольностью этих категорий итераторов.

Я также думаю, что его примеры отключены, особенно его копирование файлов: да, вариант итератора это огромное улучшение по сравнению с кодом 1975 года. Он сокращает цикл со сложным условием разрыва до одного оператора . То, с чем он действительно сталкивается, это только синтаксис. Что ж, извините: мы говорим о C ++ здесь - конечно синтаксис ужасен. И да, использование диапазонов здесь является улучшением - но только синтаксически.

Я также думаю, что реализация Андрея find отключена. Что он действительно определяет, так это операцию DropUntil (назвать сложно!) Из LINQ. Операция find должна действительно возвращать один или ноль элементов (или итератор!). Избегать итераторов здесь, на мой взгляд, бесполезно, так как мы можем захотеть изменить значение напрямую, а не копировать его. Возврат диапазона из одного элемента здесь только увеличивает издержки без выгоды. Делать это у Андрея плохо, потому что тогда название метода просто неверно и вводит в заблуждение.

Тем не менее, я, по сути, согласен с Андреем почти во всех пунктах. Итераторы, хотя и являются моей любимой концепцией в области компьютерных наук, безусловно, являются большой синтаксической нагрузкой, и многие диапазоны (особенно бесконечные генераторы) могут (и должны) быть реализованы удобно без них.

На мой взгляд, это полезно, поскольку мы можем захотеть изменить значение напрямую, а не копировать его. Возврат диапазона из одного элемента здесь только увеличивает издержки без выгоды. Делать это у Андрея плохо, потому что тогда название метода просто неверно и вводит в заблуждение.

Тем не менее, я, по сути, согласен с Андреем почти во всех пунктах. Итераторы, хотя и являются моей любимой концепцией в области компьютерных наук, безусловно, являются большой синтаксической нагрузкой, и многие диапазоны (особенно бесконечные генераторы) могут (и должны) быть реализованы удобно без них.

На мой взгляд, это полезно, поскольку мы можем захотеть изменить значение напрямую, а не копировать его. Возврат диапазона из одного элемента здесь только увеличивает издержки без выгоды. Делать это у Андрея плохо, потому что тогда название метода просто неверно и вводит в заблуждение.

Тем не менее, я, по сути, согласен с Андреем почти во всех пунктах. Итераторы, хотя и являются моей любимой концепцией в области компьютерных наук, безусловно, являются большой синтаксической нагрузкой, и многие диапазоны (особенно бесконечные генераторы) могут (и должны) быть реализованы удобно без них.

40
ответ дан 26 November 2019 в 19:49
поделиться
  1. Большинство из нас просто используют их в хорошо известных идиомах, например, в циклах for для итерации по std :: vector. Разработчик читает это и знает, что происходит. В нашей повседневной жизни программирование итераторы не являются хорошими или плохими, они просто «то, что выполняет работу».
  2. Вероятно, да.
  3. Я так не думаю.
4
ответ дан 26 November 2019 в 19:49
поделиться

Андрей временами может быть немного провокационным. Итераторы являются разумной концепцией и довольно фундаментальными в том смысле, что биты есть. Но так же, как большинство битов в C ++ не являются логическими переменными, а являются частью больших типов, большинство итераторов должны обрабатываться на высоком уровне. Андрей прав, что правильный уровень для этого - объект диапазона. Но не все диапазоны должным образом представлены как диапазоны итераторов, как показывает страж istream_iterator. Это просто взломать искусственный конечный итератор. Я не думаю, что его идеи будут приняты реализациями, все же. C ++ 1x будет таким же актуальным, как C99.

4
ответ дан 26 November 2019 в 19:49
поделиться

Я согласен с ним в том, что итераторы в основном уступают диапазонам, и я не знаю, будет ли выбрано «что-то лучшее».

«Добро - враг лучшего» "сильно играет здесь, как обычно. Итераторы полезны и прочно укоренились, поэтому трудно понять, может ли что-то лучше, например, диапазоны, вытеснить их за разумное время.

3
ответ дан 26 November 2019 в 19:49
поделиться

C ++ 0x уже делает первые шаги:

  • ссылки на rvalue решают некоторые проблемы с обработкой контейнеров, поскольку диапазоны
  • добавлены в базовую библиотеку, включая концепции диапазонов

Переход к диапазонам без потери какой-либо функциональности итератора (подумайте обо всех комбинациях категорий итераторов, константности и rvalue-ness) труден, особенно если вы пытаетесь учитывать бесконечные и изменяемые диапазоны.

3
ответ дан 26 November 2019 в 19:49
поделиться

Я думаю, что мы должны использовать диапазоны рядом с итераторами, то есть мы должны выбирать путь эволюции, а не путь революции.

2
ответ дан 26 November 2019 в 19:49
поделиться
  1. Иногда
  2. Вероятно
  3. Маловероятно, по крайней мере, в течение многих лет
1
ответ дан 26 November 2019 в 19:49
поделиться

Как и любой API или функция, при неправильном использовании может создать много проблем идентификации. Итераторы использовали во многих проектах, но всегда поддерживали необходимую заботу в соответствии с их характеристиками. Его использованию должно предшествовать хорошее понимание их ограничений. Итераторы могут быть очень полезны, если пользователь правильно.
Эти вопросы связаны с:
Есть ли способ проверить, действителен ли итератор?
Стоит ли предпочесть итераторы, а не const_iterators?

1
ответ дан 26 November 2019 в 19:49
поделиться

Я думаю, что разработчики C ++ будут в полной мере готовы предоставить полную рабочую поддержку для C ++ 0x, без реализации новых нестандартных парадигм.

0
ответ дан 26 November 2019 в 19:49
поделиться

Единственный аргумент, который я вижу из этой презентации, - это неспособность определить диапазоны, и предложение c ++ 0x «Range for Statement», похоже, в какой-то степени устраняет эту проблему. может быть, это не должно быть аргументом о том, следует ли / не следует ли использовать итераторы вообще, но более того, для каких ситуаций / не следует их использовать?

0
ответ дан 26 November 2019 в 19:49
поделиться

Я не согласен ни с Андреем, ни с Конрадом, ни со мной: -)

Самая фундаментальная концепция - это интерфейс, а не итератор, и это довольно очевидно в любой работе, которую кто-либо делает сегодня (которая связана с кросс-библиотекой, кросс-языками, кросс-компилятором, кросс-ОС, кросс-платформенностью. , вы перекрестно назовете его :-)

Ни итератор, ни диапазон (кроме использования на уровне исходного кода) не предлагают ничего, кроме чистого и простого, ненавязчивого или навязчивого, не разделяемого или разделяемого, не уникального или уникального: указателя! Чистый указатель на типизированные данные просто универсален, и вы можете сделать данные изменяемыми или неизменяемыми и многое другое. Весь интерфейс - это просто еще один уровень косвенного обращения к нему, при этом он удобен для машины и компилятора всех видов, а также гораздо безопаснее, отводя итераторы и использование диапазона к деталям реализации.

В этом отношении IEnumerable и IQueryable поступают наполовину «правильно» TM, но они явно уступают в своих концепциях итерации и многого другого по сравнению с тем, что вы можете делать с STL, сохранять контроль и так далее и так далее (но, к сожалению, у них лучшие метаданные и, следовательно, лучшая, более чистая модель). Дело в том, что с интерфейсами вы можете построить любую абстракцию, которую хотите и удовлетворить, что, вероятно, противоречиво, но, по сути, несложно: оптимальное и нейтральное во время выполнения или компиляции представление данных и код (черт возьми, это важно для алгоритмов, компиляторов, виртуальных машин и тому подобного) ,

Можно даже оптимизировать его для «динамических» / компонентных систем вплоть до встраивания «времени выполнения» (к черту HotSpot VM :-) .. В этом смысле продвижение к 1975 году минимально, о чем свидетельствует огромная рабочая нагрузка индустрии взаимодействия. (везде, куда ни глянь, включая этот сайт, использование проприетарных и открытых технологий и т. д .; в идеализме информатики, ну,

1
ответ дан 26 November 2019 в 19:49
поделиться

Разве Андрей не пытается провести скрытый маркетинг для языка D. (в настоящее время он работает над этим) ...?

Андрей утверждает, что с контейнерами все в порядке, но итераторы уродливы, не интуитивно понятны, подвержены ошибкам и опасны, их сложно реализовать (ну, последнее кажется довольно верным ...) А что у нас в C ++ ... указатели? Разве они не уродливы /.../ опасны? Но мы с радостью приняли их и живем с ними.

Какой из них проще написать:

2
ответ дан 26 November 2019 в 19:49
поделиться

Вот решение regex, которое использует категорию пунктуации, чтобы избежать необходимости указывать.!? "и т.д., хотя вы, безусловно, должны проверить, покрывает ли она ваши потребности или установить их явно. Прочитайте категорию «P» в разделе «Поддерживаемые общие категории Юникода», расположенном на странице MSDN Character Classes .

string input = @"this is some code. the code is in C#? it's great! In ""quotes."" after quotes.";
string pattern = @"(^|\p{P}\s+)(\w+)";

// compiled for performance (might want to benchmark it for your loop)
Regex rx = new Regex(pattern, RegexOptions.Compiled);

string result = rx.Replace(input, m => m.Groups[1].Value
                                + m.Groups[2].Value.Substring(0, 1).ToUpper()
                                + m.Groups[2].Value.Substring(1));

Если вы решите не использовать класс \p {P} , вам придется указать символы самостоятельно, как показано ниже:

string pattern = @"(^|[.?!""]\s+)(\w+)";

EDIT: является обновленным примером демонстрации 3 узоров. Первый показывает, как все знаки препинания влияют на обсадную трубу. Во втором примере показано, как выбрать и выбрать определенные категории знаков препинания с помощью вычитания класса. Он использует все знаки препинания при удалении определенных групп знаков препинания. Третий похож на 2-й, но использует разные группы.

В ссылке MSDN не указано, на что ссылаются некоторые категории знаков препинания, поэтому ниже приводится разбивка:

  • P : все знаки препинания (включают все перечисленные ниже категории)
  • Pc : подчеркивание _
  • Pd : тире -
  • Ps : открытые круглые скобки, скобки и скобки ( [ {
  • Pe : закрывающие скобки, скобки и скобки ) ] }
  • Pi : начальные одинарные/двойные кавычки (MSDN говорит, что «может вести себя как Ps/Pe в зависимости от использования»)
  • Pf : окончательные одинарные/двойные кавычки (применяется примечание MSDN Pi)
  • Po : другие знаки препинания, такие как запятая, двоеточие, многоточие и косая черта , , :, ; , \, /

Тщательно сравните влияние этих групп на результаты. Это должно предоставить вам большую степень гибкости. Если это не кажется желательным, можно использовать определенные символы в классе символов, как показано ранее.

string input = @"foo ( parens ) bar { braces } foo [ brackets ] bar. single ' quote & "" double "" quote.
dash - test. Connector _ test. Comma, test. Semicolon; test. Colon: test. Slash / test. Slash \ test.";

string[] patterns = { 
    @"(^|\p{P}\s+)(\w+)", // all punctuation chars
    @"(^|[\p{P}-[\p{Pc}\p{Pd}\p{Ps}\p{Pe}]]\s+)(\w+)", // all punctuation chars except Pc/Pd/Ps/Pe
    @"(^|[\p{P}-[\p{Po}]]\s+)(\w+)" // all punctuation chars except Po
};

// compiled for performance (might want to benchmark it for your loop)
foreach (string pattern in patterns)
{
    Console.WriteLine("*** Current pattern: {0}", pattern);
    string result = Regex.Replace(input, pattern,
                            m => m.Groups[1].Value
                                 + m.Groups[2].Value.Substring(0, 1).ToUpper()
                                 + m.Groups[2].Value.Substring(1));
    Console.WriteLine(result);
    Console.WriteLine();
}

Обратите внимание, что «Dash» не заглавен с помощью последнего образца и находится на новой строке. Одним из способов его оприходования является использование опции RegexOptions.Multiline . Попробуйте вышеуказанный фрагмент с этим, чтобы увидеть, соответствует ли он желаемому результату.

Также, в качестве примера, я не использовал RegexOptions.Compiled в вышеупомянутом цикле. Чтобы использовать оба варианта ИЛИ их вместе: RegexOptions.Compiled | RegexOptions.Multiline .

-121--4167102-

Это называется Проектирование по контракту .

Основная идея конструирования по контракту заключается в том, что объекты имеют контракты между ними, и если вызывающий абонент не выполняет контракт, то получатель должен отказать за исключением, а не пытаться угадать намерение вызывающего абонента. В конце дня это приводит к более стабильному программному обеспечению (в частности, когда на проекте пишет более одного человека, с тех пор контракт также становится контрактами между программистами).

PS: Важным вопросом Проектирования по Контракту, который часто забывается, является следующее. Он должен позволять клиенту знать, выполняет ли он договор или нет.если контракт стека заключается в том, что клиент может только pop , если стек не пуст, должен быть методом isEmpty , чтобы проверить, что и клиенты должны использовать этот метод перед вызовом pop . Поэтому код, в котором используется Design by Contract, загромождается с исключениями, которые, тем не менее, никогда не выбрасываются.

-121--2964805-
  1. Нет, они неплохие, на самом деле очень умные идеи. Однако они не идеальны и есть место для улучшений в концепции итератора.

  2. Он решает ряд реальных проблем с итераторами. Например, во многих случаях утомительно запрашивать два отдельных объекта, итераторы, из одного контейнера, а затем передавать их как еще два отдельных объекта в алгоритм. Почему бы не передать ни одного объекта? Даже std:: pair < итератор, итератор > мог бы создать неочищенный диапазон, которым легче манипулировать - один объект, а не два. Кроме того, рекомендуется рассмотреть диапазон является итератором . Это на самом деле то, что предлагает Андрей. К пути некоторые из этих проблем уже были решены Boost.Range .

  3. Я бы ожидал, что это произойдет, но это будет не революция, а эволюция.

3
ответ дан 26 November 2019 в 19:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: