В студийной имплементации оператора сравнения игнорируется traits с которыми он объявлен. Там тупо используется оператор == на каждый из элементов.
Что об этом говорит стандарт?
Здравствуйте, Caracrist, Вы писали:
C>В студийной имплементации оператора сравнения игнорируется traits с которыми он объявлен.
Что за traits?
Тот который ::key_compare, который strict weak ordering, который не обязательно total ordering и у которого эквивалентность не обязательно означает равенство?
C>Там тупо используется оператор == на каждый из элементов.
Здравствуйте, Caracrist, Вы писали:
C>В студийной имплементации оператора сравнения игнорируется traits с которыми он объявлен. Там тупо используется оператор == на каждый из элементов. C>Что об этом говорит стандарт?
вот что говорит cppreference http://www.cplusplus.com/reference/set/set/operators/
Operations == and != are performed by first comparing sizes, and if they match, the elements are compared sequentially using algorithm equal, which stops at the first mismatch.
Operations <, >, <= and >= behave as if using algorithm lexicographical_compare, which compares the elements sequentially using operator< reflexively, stopping at the first mismatch.
Notice that none of these operations take into consideration the internal comparison object of neither container.
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, Caracrist, Вы писали:
C>>В студийной имплементации оператора сравнения игнорируется traits с которыми он объявлен. Там тупо используется оператор == на каждый из элементов. C>>Что об этом говорит стандарт? U>вот что говорит cppreference U>http://www.cplusplus.com/reference/set/set/operators/
1-2) Checks if the contents of lhs and rhs are equal, that is, whether lhs.size() == rhs.size() and each element in lhs has equivalent element in rhs at the same position.
3-6) Compares the contents of lhs and rhs lexicographically. The comparison is performed by a function equivalent to std::lexicographical_compare.
1-2 — это == и !=, 3-6 — операторы неравенств.
Вообще, cplusplus.com уже ловили на неточностях, но я не ожидал от более доверительного cppreference.com увидеть такое расплывчатое описание.
Опыты над gcc 4.7.3 показывают: std::set в любом случае забивает на свой параметр-компаратор, и использует операторы над типом аргумента — как для равенств, так и для неравенств.
Хотя и std::equals, и std::lexicographical_compare можно параметризовать.
Вот такая неувязочка.
Не, понятно, что операторы над множеством должны быть непротиворечивы — и использовать либо только один способ (параметр-компаратор), либо другой (операторы над аргументом).
Но почему именно тот, а не другой
см "Table 96 — Container requirements" и "Table 98 — Optional container operations"
К>Хотя и std::equals, и std::lexicographical_compare можно параметризовать.
std::set параметризуется strict weak ordering, а не total ordering. Это означает, что из !cmp(x, y) && !cmp(y, x) не следует x == y.
К>Вот такая неувязочка. К>Не, понятно, что операторы над множеством должны быть непротиворечивы — и использовать либо только один способ (параметр-компаратор), либо другой (операторы над аргументом). К>Но почему именно тот, а не другой
std::set это container, "Table 96" определяет "Container requirements", где "a == b" делает то, что я показал выше.
Если бы operator== делал что-нибудь другое для set'а — тогда либо set не был бы стандартным контейнером, либо стандартный контейнер был бы без operator==, либо operator== имел бы какую-нибудь странную семантику.
Здравствуйте, Кодт, Вы писали:
К>Вот такая неувязочка. К>Не, понятно, что операторы над множеством должны быть непротиворечивы — и использовать либо только один способ (параметр-компаратор), либо другой (операторы над аргументом). К>Но почему именно тот, а не другой
Ну вот представь, что ты загружаешь откуда-нть толпу человек (ученики-дежурные на сегодня) и организуешь их в сет по классу (потому что один дежурный от каждого класса).
А потом загружаешь то же самое за вчера.
И сравниваешь.
Вот что бы ты ожидал от сегодня==вчера? Имхо, они должны считаться равными только если список дежурных не изменился со вчерашнего дня. Во всех остальных случаях (разные ученики, или от какого-то класса не прибыло дежурного вообще) они должны считаться неравными.
Иными словами, при всех сравнениях стандартных контейнеров сравниваются сами элементы, и способ хранения/упорядочения их внутри контейнера не должен никакого влияния на это сравнение оказывать.
Здравствуйте, omgOnoz, Вы писали:
O>Да они укурились со своими стандартами. Всегда знал, что 2 сета должны быть равны, если содержат одинаковый набор элементов. А тут
а тут 2 сета равны, "если содержат одинаковый набор элементов"
EP>а тут 2 сета равны, "если содержат одинаковый набор элементов"
Ну в общем да, нельзя сравнивать сеты с разными компараторами... на уровне компиляции зашибет
Здравствуйте, omgOnoz, Вы писали:
EP>>а тут 2 сета равны, "если содержат одинаковый набор элементов" O>(18:12) Если содержимое сетов по разному отсортировано? O>(18:26) Одинаковый набор элементов может быть по разному отсортирован O>(18:38) Даже если элементы set-а по разному отсортированы? O>(18:49)Ну в общем да, нельзя сравнивать сеты с разными компараторами... на уровне компиляции зашибет
А ты чего так нервничаешь?
Если у set'овских strict weak ordering разные типы — то == даже не скомпилируется (написал до того как ты удалил очередное своё сообщение).
А платить O(N*ln(N)) за то что в 99% случаев стоит O(N) — из-за того что кто-то хочет чесать правое ухо левой пяткой, я не согласен
Компаратор всегда можно написать свой, хоть за О(1). А то как оно сделано — это неприятные ограничения.
И разность типов еще определяться типом компараторов и даже аллокаторов...