Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
1

Что-то не так с transform?

17.11.2016, 17:19. Просмотров 847. Ответов 38
Метки нет (Все метки)

transform требует итераторы ввода и делает что-то такое:

C++
1
2
3
4
5
6
7
8
9
template<class InputIt, class OutputIt, class UnaryOperation>
OutputIt transform(InputIt first1, InputIt last1, OutputIt d_first,
                   UnaryOperation unary_op)
{
    while (first1 != last1) {
        *d_first++ = unary_op(*first1++);
    }
    return d_first;
}
И видим здесь:
*first1++

То есть, смещаемся к следующему элементу контейнера, БЕРЁМ СТАРОЕ ЗНАЧЕНИЕ ИТЕРАТОРА, РАЗЫМЕНОВЫВАЕМ... То же самое слева от присваивания. Но: если значение итератора ввода увеличено на единицу, нет никаких гарантий, что его можно
разыменовать по предыдущему значению (с) Прата. Это что же, возможная реализация алгоритма transform с cppreference - неправильная? Или я что-то не так понимаю?
4
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.11.2016, 17:19
Ответы с готовыми решениями:

Как сделать так что я мог умножать не на два числа а на 3,4,5 и так далее?
Вот код: #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int...

Что в коде ни так? while не работает так, как ожидаю
Написанный код, как я думаю, должен выдавать цифры от 0 до 1000, столбиком. Но...

Что-то не то с Майкрсофт визуал студио 2010 или я что-то не так делаю
Дело в том что при запуске вот этой программы: #include &lt;iostream&gt; using...

Что в программе делает так, что процессор грузится на 100%?
Я не очень разбираюсь в С++, поэтому прошу вашей подсказки по поводу нагрузки...

Список: Что не так с выводом списка, потому что выводится какой-то мусор?
#include &lt;iostream&gt; using namespace std; struct point { int...

38
nmcf
6277 / 5578 / 2539
Регистрация: 14.04.2014
Сообщений: 23,471
17.11.2016, 18:00 2
В цикле же проверяется условие, а инкремент после разыменования.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 18:06  [ТС] 3
Инкремент как раз до разыменования, у него приоритет выше (см. любую таблицу). У постфиксных приоритет выше, чем у разыменования.
При чём тут условие цикла?
0
nmcf
6277 / 5578 / 2539
Регистрация: 14.04.2014
Сообщений: 23,471
17.11.2016, 18:15 4
Да, выше, но сама операция постфиксного инкремента возвращает старое значение.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 18:23  [ТС] 5
Вот! Старое значение! И тут мы возвращаемся к цитате из Прата (и по большому счёту любого другого учебника): если значение итератора ввода увеличено на единицу, нет никаких гарантий, что его можно
разыменовать по предыдущему значению
. В соответствии с этим утверждением, мы можем получить чушь. Либо я что-то не так понимаю.
0
Mr.X
Эксперт С++
3180 / 1707 / 435
Регистрация: 03.05.2010
Сообщений: 3,867
17.11.2016, 18:36 6
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Вот! Старое значение! И тут мы возвращаемся к цитате из Прата (и по большому счёту любого другого учебника): если значение итератора ввода увеличено на единицу, нет никаких гарантий, что его можно
разыменовать по предыдущему значению. В соответствии с этим утверждением, мы можем получить чушь. Либо я что-то не так понимаю.
Ну да, не понимаете отличия постфиксного инкремента от префиксного . В Си он специально был выдуман для подобных действий с указателями.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 18:40  [ТС] 7
Это вы не поняли вопроса.
Ещё раз. Логика такая: смещаем итератор к следующему элементу. Затем разыменовываем старое значение, возвращённое инкрементом. Старое. Этого делать нельзя, в соответствии с цитатой, либо она имеет другой смысл. Если смысл другой, то мне хотелось бы узнать, какой именно. Так яснее? Что в этой логической цепочке неправильно?
Это не указатель, это итератор с гораздо меньшим функционалом. В том-то и проблема. С указателем так сделать можно. С итератором ввода/вывода - не факт, о чём и речь.
0
castaway
Эксперт С++
4932 / 3038 / 454
Регистрация: 10.11.2010
Сообщений: 11,117
Записей в блоге: 10
Завершенные тесты: 1
17.11.2016, 18:43 8
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Вот! Старое значение!
Значение старое, а итератор новый.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 18:44  [ТС] 9
Значение старое, а итератор новый.
Что из этого следует? Итератор новый, а мы используем старое значение, которое вроде как использовать нельзя.
0
castaway
Эксперт С++
4932 / 3038 / 454
Регистрация: 10.11.2010
Сообщений: 11,117
Записей в блоге: 10
Завершенные тесты: 1
17.11.2016, 18:48 10
Разименование происходит до изменения итератора.

Разработчики стандартной библиотеки C++ наверное тоже читали Прата...
C++
1
2
3
value_type x = *i;
++i;
return x;
http://en.cppreference.com/w/cpp/concept/InputIterator
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 18:49  [ТС] 11
Каким образом, когда у инкремента приоритет выше?
Ходим кругами.

Апд. Да, странная реализация, интуитивно ожидается что-то другое.
Какова же может быть реализация этого вот и какой смысл тогда имеет процитированная фраза?
0
castaway
Эксперт С++
4932 / 3038 / 454
Регистрация: 10.11.2010
Сообщений: 11,117
Записей в блоге: 10
Завершенные тесты: 1
17.11.2016, 18:52 12
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Каким образом
Я ссылку для кого оставил?
Смотрите реализацию перегруженного оператора постфиксного инкремента для InputIterator.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 18:53  [ТС] 13
Ссылка появилась после редактирования.
Так какой же тогда смысл у фразы и как обеспечивается нужное поведение итератора? Я так понимаю, приведён псевдокод.
0
IGPIGP
Комп_Оратор)
Эксперт по математике/физике
7059 / 3362 / 455
Регистрация: 04.12.2011
Сообщений: 9,350
Записей в блоге: 5
17.11.2016, 19:46 14
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
То же самое слева от присваивания. Но: если значение итератора ввода увеличено на единицу, нет никаких гарантий, что его можно разыменовать по предыдущему значению (с) Прата.
Фраза более чем странная, в данной ситуации. Приведите точную ссылку (назв. книги, издание, глава, страница...).
При реализации пост-инкремента, стандартно, используется временный объект значения, хранящий значение до инкремента. Поэтому не ясно какое отношение данная фраза имеет к вопросу. Тут важен контекст в котором она звучит в книге.
0
Mathist
57 / 53 / 33
Регистрация: 18.04.2014
Сообщений: 121
Завершенные тесты: 2
17.11.2016, 19:54 15
kozlik_kozlik, так как в данном выражении *d_first++ = unary_op(*first1++);
используется постфиксная запись, то увеличение итераторов произойдет после вычисления выражения.
Т.е. это эквивалентно записи:
C++
1
2
3
*d_first = unary_op(*first1);
++d_first;
++first1;
Да, приоритет операции постинкримента выше, но выполняется она после вычисления выражения.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 20:08  [ТС] 16
При реализации пост-инкремента, стандартно, используется временный объект значения, хранящий значение до инкремента. Поэтому не ясно какое отношение данная фраза имеет к вопросу. Тут важен контекст в котором она звучит в книге.
А нет контекста. И примеров нет, собственно почему вопрос и возник.

Итератор ввода позволяет получить доступ ко всем значениям в контейнере.
Он выполняет это, поддерживая операцию ++ и в префиксной, и в постфиксной
формах. Если итератор ввода установлен на первый элемент контейнера, а затем его значение увеличивается до тех пор, пока не будет достигнут элемент, находящийся за пределами контейнера, то итератор будет указывать
на каждый элемент контейнера только один раз. В связи с этим нет никаких
гарантий, что при обходе контейнера второй раз итератор ввода пройдет по
значениям в таком же порядке, как раньше. К тому же, если значение
итератора ввода увеличено на единицу, нет никаких гарантий, что его можно
разыменовать по предыдущему значению. Следовательно, всякий алгоритм,
базирующийся на итераторе ввода, должен быть однопроходным, т.е. не
требующим значений итератора, определенных при прошлом прохождении
контейнера, или предыдущих его значений при текущем прохождении.
Заметьте, что итератор ввода односторонний; его значение можно увеличить,
но нельзя вернуться назад.
Например
0
Toshkarik
1149 / 866 / 90
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
17.11.2016, 20:21 17
Мне не понятно почему Вам не понятно Все логично. Берется текущее значение итератора, которое валидно. Отдается оператору разыменовывания. Это, как принято говорить, синтаксический сахар. Под валидностью/невалидностью тут, как мне кажется, имеется ввиду попытка доступа к старым значениям итератора после изменения самого контейнера. Изменение самого итератора никак не должно на это влиять.
0
castaway
Эксперт С++
4932 / 3038 / 454
Регистрация: 10.11.2010
Сообщений: 11,117
Записей в блоге: 10
Завершенные тесты: 1
17.11.2016, 20:31 18
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
А нет контекста.
А ниже этого сообщения вы что привели?


Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Так какой же тогда смысл у фразы и как обеспечивается нужное поведение итератора?
Смысл: нельзя сохранять предыдущее значение итератора.
Как обеспечить: не использовать предыдущее значение итератора.

Вы внимательно читали текст по ссылке которую я вам давал?
InputIterators only guarantee validity for single pass algorithms: once an InputIterator i has been incremented, all copies of its previous value may be invalidated.
Добавлено через 2 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
имеется ввиду попытка доступа к старым значениям итератора после изменения самого контейнера.
Как я понял, изменение контейнера тут не подразумевается, по крайней мере я нигде этого не вычитал.
0
kozlik_kozlik
7 / 11 / 0
Регистрация: 01.08.2012
Сообщений: 99
17.11.2016, 20:35  [ТС] 19
А ниже только следствие без пояснений.

InputIterators only guarantee validity for single pass algorithms: once an InputIterator i has been incremented, all copies of its previous value may be invalidated.
Во что конкретно это выливается? Каков механизм?

Добавлено через 2 минуты

Не по теме:

Не по теме:

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

0
castaway
Эксперт С++
4932 / 3038 / 454
Регистрация: 10.11.2010
Сообщений: 11,117
Записей в блоге: 10
Завершенные тесты: 1
17.11.2016, 20:36 20
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Во что конкретно это выливается?
В UB.

Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Каков механизм?
Не оговорен стандартом.

Добавлено через 37 секунд
Цитата Сообщение от kozlik_kozlik Посмотреть сообщение
Правильно, если старожил ошибается, это простительно. А новичку можно и нахамить за вопрос. Действительно, чего церемониться.
Вы сейчас о чём? Поясните.
1
17.11.2016, 20:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.11.2016, 20:36

Лучший интерактивный самоучитель с++, но так понравился, что думаю, а что если после python изучать с++?
http://academy.cppstudio.com/courses/ 1.) поделитесь опытом после какого языка...

Как сделать так,что бы при введение,например 0;0 выдавалось сообщение,что точка находится на границе?
#include &lt;iostream&gt; using namespace std; int main(){ double...

Ребят Незнаю что делать при запуске на компилирование выдает ошибку.Кто понимает что не так скажите а если не затруднит исправьте ошибку
Разговаривал с двумя преподами говорят что проект не правильно создавал,хотя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru