Здравствуйте, Сыроежка, Вы писали:
C>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap?
pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
Здравствуйте, Сыроежка, Вы писали:
С>Дело в том, что когда вы цитируете описание std::map, вы просто перечисляете открытый интерфейс этого контейнера, то есть те функции-члены, которые есть в контейнере. Но при этом никак не можете понять, что ключ и отображаемое значение — это независимые между собой части. В том смысле, что один раз завяде элемент контейнера, вы затем отображаемое значение этого элемента можете менять сколько угодно раз. Но хуже того, вы даже сами не понимаете то, что цитируете. Вы цитируете сходство с вектором, не понимая того, что имеется виду общий способ обращения по ключу к элементу, только у вектора этот ключ имеет заранее определенный тип unsigned int, и сами ключи должны следовать без пропусков. Что это означает? Это означает, что лишь организован доступ по ключу, но пользователь работает с отображаемыми объектами! Ключ играет роль индекса к элементу, а изменяется именно отображаемое значение. Работает пользовательна самом деле не с парой, так как первый элемент пары — это константное значение, а именно с отображаемым значением. Ключи создаются только раз и больше никакой роли кроме роли индекса к элементу не играют. Далее пользователь работает с отображаемым значением, модифицируя его по мере необходимости и пока элемент не будет удален. То есть изменение элемента относится именно к отображаемому значению, а не ключу. Поэтому реверсировать отображаемые значения для std::map это также естественно, как и для вектора, так как реверсия — это ничто иное, как изменение хранимых значений, а контейнеры для того и существуют, чтобы можно было менять значения.
std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
Re[18]: Разместить в обратном порядке отображаемые значения
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap.
R>C++ Standart 2003, 25.2.9 Reverse:
R>
R>For each non-negative integer i <= (last — first)/2, applies iter_swap to all pairs of iterators first + i, (last — i) — 1.
R>C++ Standart 2003, 25.2.2 Swap:
R>
R>template<class T> void swap(T& a, T& b);
R>Requires: Type T is CopyConstructible (20.1.3) and Assignable (23.1).
R>C++ Standart 2003, 23.1 Container requirements, Table 64—Assignable requirements:
R>
R>expression | return type | post-condition
R>-------------------------------------------------
R>t = u | T& | t is equalent to u
R>-------------------------------------------------
R>In the map class template, these are bidirectional iterators.
R>Dereferencing this iterator accesses the element's value, which is of type pair<const Key,T>.
R>Следовательно, pair<const Key,T> не может использовать swap. На мой взгляд, стандарт последователен в данном случае.
С>>Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает. То есть я вообще мог здесь не распинатьсяы, а указать просто на то, что стандарт не выполняет своих обязательств. То есть он был по крайней мере в разделе стандартных алгоритмов для этого алгоритма указать все исключения его применения, если основные требования выполнены, такие, как, например, наличие двустороннего итератора. Но этого нет. Этого вполне достатончо, чтобы заявить, что стнадарт содержит серьезные упущения.
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Сыроежка, Вы писали:
С>>Дело в том, что когда вы цитируете описание std::map, вы просто перечисляете открытый интерфейс этого контейнера, то есть те функции-члены, которые есть в контейнере. Но при этом никак не можете понять, что ключ и отображаемое значение — это независимые между собой части. В том смысле, что один раз завяде элемент контейнера, вы затем отображаемое значение этого элемента можете менять сколько угодно раз. Но хуже того, вы даже сами не понимаете то, что цитируете. Вы цитируете сходство с вектором, не понимая того, что имеется виду общий способ обращения по ключу к элементу, только у вектора этот ключ имеет заранее определенный тип unsigned int, и сами ключи должны следовать без пропусков. Что это означает? Это означает, что лишь организован доступ по ключу, но пользователь работает с отображаемыми объектами! Ключ играет роль индекса к элементу, а изменяется именно отображаемое значение. Работает пользовательна самом деле не с парой, так как первый элемент пары — это константное значение, а именно с отображаемым значением. Ключи создаются только раз и больше никакой роли кроме роли индекса к элементу не играют. Далее пользователь работает с отображаемым значением, модифицируя его по мере необходимости и пока элемент не будет удален. То есть изменение элемента относится именно к отображаемому значению, а не ключу. Поэтому реверсировать отображаемые значения для std::map это также естественно, как и для вектора, так как реверсия — это ничто иное, как изменение хранимых значений, а контейнеры для того и существуют, чтобы можно было менять значения.
I>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
Так сложности нет и в том, чтобы написать все стандартные алгоритмы! Только зачем каждый раз это делать, вы можете объяснить? Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size().
Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Почему это к std::pair нельзя применить swap?
R>У меня было написано, что к std::pair<const Key,T> нельзя применить swap.
R>Вот здесь
Здравствуйте, Masterkent, Вы писали:
M>Сыроежка:
С>>Здесь вопрос не о включении абсолютно всего, так как стандартный алгоритм уже включен в библиотеку. То есть нужно лишь сделать так, чтобы std::map не остался не охваченным.
M>Ну, можно было бы ввести трансформирующие итераторы для работы с mapped values.
Ну так все это в бусте сто лет есть, просто Сыроежке шашечки нужны, а не ехать. У него даже задачи нет, в которой это могло бы понадобиться, кроме задачи обозвать никому сто лет не нужную функцию "существенным упущением стандарта".
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
C>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма. Эта форма алгоритма напрашивается не только для std::map, а может быть применима для любого типа контейнера, когда мы ходим менять не целиком элементы, а их части. То есть имеется, например, достаточно гибкая форма алгоритма std::transform, алгоритм std:;reverse тоже заслуживает того, чтобы приобрести большую гибкость. Как я указывал, приведенный в начале дискуссии пример самодельного такого алгоритма совершенно не удовлетворителен. Он даже не работает, если нужно реверсировать не весь контейнер, а всего лишь его диапазон. А наличие формы контейнера std::reverse.которую я привел, решала бы все проблемы.
Вот как, например, выглядел бы тогда соответсвующий код
Здравствуйте, Сыроежка, Вы писали:
I>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>Так сложности нет и в том, чтобы написать все стандартные алгоритмы!
Раз нет сложности, то напиши и используй.
С>Только зачем каждый раз это делать, вы можете объяснить?
Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит.
Даже если вас съели, у вас как минимум два выхода.
Re[21]: Разместить в обратном порядке отображаемые значения
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Сыроежка, Вы писали:
C>>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
С>Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма. Эта форма алгоритма напрашивается не только для std::map, а может быть применима для любого типа контейнера, когда мы ходим менять не целиком элементы, а их части. То есть имеется, например, достаточно гибкая форма алгоритма std::transform, алгоритм std:;reverse тоже заслуживает того, чтобы приобрести большую гибкость. Как я указывал, приведенный в начале дискуссии пример самодельного такого алгоритма совершенно не удовлетворителен. Он даже не работает, если нужно реверсировать не весь контейнер, а всего лишь его диапазон. А наличие формы контейнера std::reverse.которую я привел, решала бы все проблемы.
С>Вот как, например, выглядел бы тогда соответсвующий код
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, rumit7, Вы писали:
R>>Здравствуйте, Сыроежка, Вы писали:
С>>>Почему это к std::pair нельзя применить swap?
R>>У меня было написано, что к std::pair<const Key,T> нельзя применить swap.
R>>Вот здесь
Вам ответили почему.
R>А там наверху я для кого приводил цитату из стандарта? Прочитайте требования для swap.
Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным. То есть фя уже приводил аналогию с вектором, у которого ключ, то есть индекс элементов является константным, но переставляем мы же не индексы элементов, а хранимые значения. То же самое и с отображением. первый элемент пары служит ключом, то есть индексом хранимого значения. Мы его так и используем для индексации элементов, но меняем же мы хранимые значения. И я самого начала предлагал реверсировать хранимые значения. Именно поэтому я и предлагаю новую форму алгоритма std:;reverse с предикатом, с помощью которого можно извлечь из итератора хранимое значение и его обменять с другим таким же значением.
Здравствуйте, Masterkent, Вы писали:
M>IMHO, в стандартной библиотеки есть куда более неприятные пробелы — например, отсутствие у файловых потоков конструктора, принимающего имя файла в юникоде (что для меня во многих случаях делает такие потоки бесполезными).
Я так понимаю, все вопросы к базовой fopen, строчка просто переправляется туда без изменений:
It then opens a file, if possible, whose name is the NTBS s (‘‘as if’’ by calling std::fopen(s,modstr)).
Т.е. если fopen может открыть файл с юникодным именем (на которое имеется голый указатель сhar*), то и fstream сможет.
Сам не проверял, если что, мне юникод не нужен
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, Сыроежка, Вы писали:
I>>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>>Так сложности нет и в том, чтобы написать все стандартные алгоритмы! I>Раз нет сложности, то напиши и используй.
С>>Только зачем каждый раз это делать, вы можете объяснить? I>Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
I>Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит. I>Даже если вас съели, у вас как минимум два выхода.
Вызнаете разницу между тем, что алгоритм присутствует в стандарте, и во всех проектах используется этот алгоритм, и тем, что в каждом команда разрабатывает свой алгоритм?
В том-то и проблема, что как раз в стандарте не хватает той формы алгоритма, которую я здесь уже привел. Она органически всотребована для многих задач. Даже если рассмотреть аткую простую задачу, как если бы вектор хранилл в качестве элементов некую структуру, и нужно реверсировать не целиком всю структуру, а лишь некоторые ее поля, то уже возникает сложность, так как нет подходящего средства!
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, Сыроежка, Вы писали:
C>>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
С>Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма.
Проблему свопа пар с константой решить нельзя в принципе.
Новая форма алгоритма для мапа также не нужна, на этот счет есть бритва Оккама.
map предоставляет двунаправленный итератор по парам ключ+значение.
Используя Boost.Iterator, можно легко превратить этот итератор в двунаправленный же итератор по значениям, после чего можно применять к нему любые стандартные алгоритмы, включая reverse, random_shuffle, permutation и т.д.
Это — единственный осмысленный путь, а то, что предлагаешь ты — концептуально неправильно.
Здравствуйте, Сыроежка, Вы писали:
С>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
Так что — нарушает стандарт или нет?
Re[22]: Разместить в обратном порядке отображаемые значения
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, Сыроежка, Вы писали:
С>>Здравствуйте, jazzer, Вы писали:
J>>>Здравствуйте, Сыроежка, Вы писали:
C>>>>>Не выполняется, поскольку итератор указывает на std::pair<const KeyT, ValueT>.
С>>>>Во-первых, почему std::pair не является swapable? Вы не можете к объектам этого класса применить алгоритм swap? J>>>pair является swapable только если его элементы являются swapable, что в случае map, очевидно, не так.
С>>Я уже показал, как можно легко решить пробллему, если ввети новую форму алгоритма. J>Проблему свопа пар с константой решить нельзя в принципе. J>Новая форма алгоритма для мапа также не нужна, на этот счет есть бритва Оккама. J>map предоставляет двунаправленный итератор по парам ключ+значение. J>Используя Boost.Iterator, можно легко превратить этот итератор в двунаправленный же итератор по значениям, после чего можно применять к нему любые стандартные алгоритмы, включая reverse, random_shuffle, permutation и т.д. J>Это — единственный осмысленный путь, а то, что предлагаешь ты — концептуально неправильно.
Я как раз не вижу ничего осмысленного в этом пути. Это как раз путь через одно место. Нужно использовать третьестороннюю библиотеку, которую не всегда разоешается использовать в проектах. Во-вторых, нужны всякие преобразования итераторов, которые затрудняют чтение кода. Так что я с вами не сооглашусь.
Самый простой пути — это тот, который я привел в вииде конерктного кода. Он совершенно ясен для читающегог код и не требует никаких ухищрений. Более того эту форму алгоритма можно использзовать не обязательно с sttd::map, но и в ттех случаях, когда надо реверсировать не полностью элемент такой, как, например, структура, а лишь отдельные ее члены. Тогда у вас снова возникает трудноразрешимая задача, если у вас нет такой формы алгоритма.
Попробуйте решить такую простую задачу, когда у вас есть вектор структур и надо реверсировать только пару полей этой структуры для диапазона элементов вектора. Что делать в этом случае?
Проблема в том, что нет формы алгоритма std::reverse с предикатом. То есть для пользователя этот алгоритм как черный ящик, в процесс работы которого нельзя вмешаться. Предоставление формы этого алгоритма с предикатом очень хорошо вписывается в общую архитектуру стандартных алгоритмов.
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, Igore, Вы писали:
I>>Здравствуйте, Сыроежка, Вы писали:
I>>>>std::map<int, int> не равен std::vector<int>, std::map<int, int> приблизительно равен std::vector<std::pair<int, int>>, ты забываешь простые вещи, stl контейнеры гарантируют времена: доступ к элементу, вставки, удаление. Ты в свою угоду хочешь все выкинуть. В общем флаг тебе в руки, напиши свою STL выложи в общий доступ и завоевывай пользователей.
I>>>>И я не понимаю в чем для тебя сложность написать 3 строчки кода который будет переворачивать значения map. В стандарте много чего нету, пиши свою библиотеку и используй ее.
С>>>Так сложности нет и в том, чтобы написать все стандартные алгоритмы! I>>Раз нет сложности, то напиши и используй.
С>>>Только зачем каждый раз это делать, вы можете объяснить? I>>Не могу объяснить, пишешь 1 раз и используешь во всех своих проектах, зачем каждый раз писать надо у тебя спросить
С>>>Зачем программистам каждый раз изобретать велосипед. более того привденный здесь в самом начале пример кода такоого доморощенного алгоритма, говорит о том, что это чревато лишь ошибками! То есть приведенный кодт не просто плох, он не выполняет поставленной задачи, если рассматривать не весь контейнер, а некоторый его диапазон, так как в коде используется функция-член класса size(). С>>>Я уже написал, какую нужно включить в стандарт форму алгоритма reverse, чтобы вопрос был решен достаточно просто.
I>>Изобретением велосипеда пока занимаешься только ты, бери стандартные контейнеры, стандартные алгоритмы и используй их. Любую задачу можно решать множеством путей, то что ты видишь только 1 и он не находится в STL ни о чем не говорит. I>>Даже если вас съели, у вас как минимум два выхода.
С>Вызнаете разницу между тем, что алгоритм присутствует в стандарте, и во всех проектах используется этот алгоритм, и тем, что в каждом команда разрабатывает свой алгоритм?
Повторю еще раз, то что тебе написали, пиши в комитет с просьбой включения в стандарт нового алгоритма. Или создай свою STL с блэкджеком и ну ты понял, разрекламируй ее и может она станет еще одним de facto, как буст, можешь туда попробовать добавить свои идеи
С>В том-то и проблема, что как раз в стандарте не хватает той формы алгоритма, которую я здесь уже привел. Она органически всотребована для многих задач. Даже если рассмотреть аткую простую задачу, как если бы вектор хранилл в качестве элементов некую структуру, и нужно реверсировать не целиком всю структуру, а лишь некоторые ее поля, то уже возникает сложность, так как нет подходящего средства!
Тебе уже несколько раз объясняли, я повторю, map<int, int> = vector<pair<const int, int>>, тогда reverse это просто обход в обратном порядке, так как лезть во внутренее устройства map мы не можем.
С>реверсировать не целиком всю структуру, а лишь некоторые ее поля
Это трансформация а не реверсирование.
Реверсирование просто и понятно, а тебе хочется немного другого, я бы на твоем месте сменил тип контейнера и не мучился
Здравствуйте, Сыроежка, Вы писали:
С>Я как раз не вижу ничего осмысленного в этом пути. Это как раз путь через одно место. Нужно использовать третьестороннюю библиотеку, которую не всегда разоешается использовать в проектах. Во-вторых, нужны всякие преобразования итераторов, которые затрудняют чтение кода. Так что я с вами не сооглашусь.
Ничего они не затрудняют в пользовательском коде, посмотри на boost.range.
С>Самый простой пути — это тот, который я привел в вииде конерктного кода. Он совершенно ясен для читающегог код и не требует никаких ухищрений. Более того эту форму алгоритма можно использзовать не обязательно с sttd::map, но и в ттех случаях, когда надо реверсировать не полностью элемент такой, как, например, структура, а лишь отдельные ее члены. Тогда у вас снова возникает трудноразрешимая задача, если у вас нет такой формы алгоритма.
Тебе придется написать такого рода специальные версии всех остальных алгоритмов, которые полагаются на swap (а в С++11 — еще и move).
random_shuffle, например, да и sort туда же.
Здравствуйте, rumit7, Вы писали:
R>Здравствуйте, Сыроежка, Вы писали:
С>>Я согласен, что ключ является константным, тем не мене само отображаемое значение не является константным.
R>Прекратите прыгать из стороны в сторону. Цитаты из стандарта я привел в ответ на то, что стандарт что-то там нарушает. Вот Ваше же высказывание:
R>
R>Кстати сказать, вы хорошо сделали, что напомнили стандарт. Если вы посмотрите главу 25 стандарта, где описаны стандартные алгоритмы, и параграф, где описан непосредственно алгоритм std::reverse, то единственные требования к этому алгоритму — это чтобы был по итератор не ниже двустороннего, а величины, на которые указывает итератор, были бы заменяемы, то есть могли использовать swap. Никаких других ограничений нет, и тем более нет упоминания в качестве иселючения для применения контейнера std::map. Это обязательство стандарта по применению алгоритма. И сам же стандарт его нарушает.
R>Так что — нарушает стандарт или нет?
Здесь не все так просто, как кажэется, так как вы можете специализировать функцию swap для элементов вашего контейнера. Так что это на усмотрение пользователя контейнера, предоставляет он такую функцию или нет.