Должен ли std :: less соответствовать оператору равенства для типов указателей? - PullRequest
13 голосов
/ 16 марта 2011

Вчера я столкнулся с проблемой, которую я в конечном итоге привел к следующему минимальному примеру.

#include <iostream>
#include <functional>

int main()
{
    int i=0, j=0;
    std::cout
        << (&i == &j)
        << std::less<int *>()(&i, &j)
        << std::less<int *>()(&j, &i)
        << std::endl;
}

Эта конкретная программа при компиляции с использованием MSVC 9.0 с включенной оптимизацией выдает 000. Это означает, что

  1. указатели не равны, а
  2. ни один из указателей не упорядочен раньше другого согласно std::less, подразумевая, что два указателя равны в соответствии с общим порядком, наложенным std::less.

Правильно ли это поведение? Разве общий порядок std::less не требуется согласовывать с оператором равенства?

Разрешается ли следующей программе выводить 1?

#include <iostream>
#include <set>

int main()
{
    int i=0, j=0;
    std::set<int *> s;
    s.insert(&i);
    s.insert(&j);
    std::cout << s.size() << std::endl;
}

Ответы [ 2 ]

11 голосов
/ 16 марта 2011

Кажется, у нас стандартное нарушение!Паника!

После 20.3.3 / 8 (C ++ 03):

Для шаблонов больше, меньше, больше_эквивалента и меньше_эквивалента специализации для любого типа указателя дают общеепорядок, даже если встроенные операторы <,>, <=,> = не делают.

Кажется, что ситуация, когда активные оптимизации приводят к неправильному коду ...

Редактировать: C ++ 0x также держит это значение под 20.8.5 / 8

Редактировать 2: Любопытно, как ответ на второй вопрос:

После 5.10 / 1 C ++ 03:

Два указателя одного типа сравниваются равными, если и только если они оба равны нулю, оба указывают на одну и ту же функцию или оба представляют одну и ту же функциюадрес

Что-то здесь не так ... на многих уровнях.

0 голосов
/ 16 марта 2011

Нет, результат явно не правильный.

Однако MSVC, как известно, не следует правилам «уникального адреса» в письме.Например, он объединяет функции шаблонов, которые генерируют идентичный код.Тогда эти разные функции также будут иметь один и тот же адрес.

Я полагаю, что ваш пример будет работать лучше, если вы действительно сделаете что-то с i и j, в отличие от их адреса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...