std::set вставка элемента

Тема в разделе "LANGS.C", создана пользователем srm, 12 авг 2011.

  1. srm

    srm New Member

    Публикаций:
    0
    Регистрация:
    14 июн 2011
    Сообщения:
    189
    Я вставляю элемент A в std::set S такой, что несколько элементов в S равны A:

    std::pair<iterator, bool> res = S.insert(A);

    В итоге res.second == false. Вопрос: на какой из элементов будет указывать res.first? Опыты показали, что на последний. Всегда ли будет так?
     
  2. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    srm
    Implementation dependent, я думаю. Вообще, insert не для этих целей. Вместо него есть lower_bound и upper_bound.
     
  3. phprus

    phprus New Member

    Публикаций:
    0
    Регистрация:
    18 авг 2006
    Сообщения:
    16
    srm
    Это невозможно. std::set хранит только уникальные значения.

    Цитата из исходников libstdc++:
    Из этого следует, что итератор из пары указывает на вставленный или на уже существующий элемент. А bool из пары показывает, вставлялся ли элемент реально или он там уже был.
     
  4. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    phprus
    Возможно. Под равенством в данном случае понимается эквивалентность согласно терминологии стандарта. А эквивалентность не обязана быть транзитивной. Т.е. в std::set могут быть два элемента a ≠ b, каждый из которых эквивалентен вставляемому элементу c: a = с и b = c.
     
  5. phprus

    phprus New Member

    Публикаций:
    0
    Регистрация:
    18 авг 2006
    Сообщения:
    16
    l_inc
    А как реализовать не транзитивную эквивалентность, если std::set выводит все операции сравнения из пользовательской реализации оператора "<" (меньше)?

    Те A == B когда (!(A < B) && !(B < A)).
     
  6. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
  7. phprus

    phprus New Member

    Публикаций:
    0
    Регистрация:
    18 авг 2006
    Сообщения:
    16
    l_inc
    Действительно возможно.

    Но тогда, если я правильно понимаю пункт 25.3 стандарта:
    использование такого оператора сравнения будет не допустимо, так как работоспособность не гарантируется.

    std::set требует (пункт 23.1.2):
    По материалам стандарта C++2003.
     
  8. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    phprus
    Ну... недопустимо — это сильно сказано. Просто не поддерживается стандартом. :)
    Я ведь упомянул в указанной теме, что транзитивность нарушена, но это нестрашно.