Универсальный меньше для указателей в стандарте C ++
Много раз мне нужен набор указателей. Каждый раз, когда это происходит, я заканчиваю тем, что пишу меньше для типа указателя – бросает два указателя на size_t и сравнивает результаты.
Мой вопрос: есть ли в стандарте? Я не мог найти ничего подобного. Кажется, достаточно распространенный случай …
Обновление: кажется, что следующий стандарт исправляет все проблемы с меньшим значением , предусмотренным для типов указателей и unordered_set. Через несколько лет этот вопрос будет спорным.
- Как скрыть окно cmd во время запуска пакетного файла?
- Компилятор Неопределенная ошибка вызова - анонимный метод и группа методов с Func или действием
- Почему в C # существуют абстрактный class и интерфейс?
- Как специализировать std :: hash :: operator () для пользовательского типа в неупорядоченных контейнерах?
- MVC Razor рассматривает вложенную модель foreach
В то же время текущий стандарт не имеет «законного» решения для этого, но cast_ size_t работает.
Обновление для обновления: ну, я буду gobsmacked! Не только
std::map<void *, int, std::less > myMap;
работает, но даже
std::map myMap;
также.
И это в gcc 3.4.1. Я делал все эти броски ни для чего, и лифчик совершенно прав. Даже номер раздела, который он цитирует, точно совпадает с текущим стандартом. Ура!
- Аспектно-ориентированное программирование в C #
- Как я могу вызвать (Iron) код Python из приложения C #?
- C: Приведение минимального 32-битного целого числа (-2147483648) к float дает положительное число (2147483648.0)
- Условный атрибут «Browsable»
- Создание случайного десятичного числа в C #
- Неразумно ли игнорировать предупреждение gcc / clang «-Смесительные скобки»?
- Дефекты выпуклости C ++ OpenCv
- Как ограничить доступ к вложенному члену classа включению classа?
Два указателя можно сравнить с использованием объектов функции сравнения less
, greater
и т. Д. В противном случае, используя operator<
одеяло» operator<
т. Д., Это возможно только в том случае, если указатели указывают на элементы одного и того же объекта массива или один за другим. В противном случае результаты не заданы.
20.3.3/8
в C ++ 03
Для шаблонов
greater
,less
,greater_equal
иless_equal
специализации для любого типа указателя дают полный порядок, даже если встроенные операторы<
,>
,<=
,>=
не делают.
Не нужно явно специализировать и вручную кастинг для size_t
: это снизит переносимость даже, поскольку отображение reinterpret_cast
от указателей к целым является реализацией, и не требуется давать какой-либо заказ.
Изменить : более подробный ответ см. В этом разделе.
Даже если вы можете подумать, что сравнение бит указателей безвредно (в конце концов, это просто адреса в памяти, верно?), Есть веские причины, по которым языковой стандарт не поощряет его. Например, если у вас есть код, результаты которого зависят от относительного упорядочения указателей (например, порядок результатов зависит от порядка итерации через набор или карту указателей), результаты будут неустойчивыми: изменение версии компилятора или операционной системы релиз может изменить результаты. Воспроизводимость достаточно ценна, чтобы избежать этой неустойчивости.
Нет, он недоступен. В стандарте говорится, что указатели сравнимы только со встроенными операторами, когда они указывают на один и тот же массив или другой блок памяти. То есть, блок должен быть выделен сразу, в отличие от двух отдельных распределений, которые могут оказаться смежными друг с другом.
Хорошо:
int x[2]; bool b = &x[0] < &x[1];
Это не определено:
int x0; int x1; bool b = &x0 < &x1;
Хорошо:
struct foo { int x0; int x1; }; foo f; bool b = &f.x0 < &f.x1;
Оба значения являются членами одной и той же структуры, поэтому они принадлежат одному блоку памяти (а именно f
).
Практически, однако, нет ничего плохого в вашем пользовательском сравнении.
Однако ваша специализированная специализация не нужна, поскольку шаблон std::less
определен для указателей, очевидно. Итак, все в порядке:
int x0; int x1; std::less compare; bool b = compare(&x0, &x1);
Пока не указано, какой результат должен быть, но вы по крайней мере обещали получить какой-то результат, а не неопределенное поведение. Вы получаете полный заказ, но вы не знаете, какой заказ, пока не запустите его.
Сравнение указателей – довольно чреватый бизнес. Имеет смысл сравнивать указатели, если они оба указывают на один и тот же блок памяти, иначе операция не определена. Таким образом, A (действительный) набор указателей является довольно специализированной вещью, и нет, в стандартной библиотеке их нет.
Сравнение указателей, которые не выделены в одном блоке, не определено, вероятно, потому, что есть модели памяти, у которых есть проблемы с ними (и они были более распространены).
Вам нужно использовать unordered_set<>
, который, как представляется, не требует оператора сравнения. Он находится в следующем стандарте C ++ и доступен как заголовок Boost тем временем.
Не hash_set
что вам нужно? Он будет частью следующего стандарта