2014-11-26 2 views
3

При внедрении оператора компаратора внутри пользовательского класса для std::map я столкнулся с этим вопросом и не мог видеть, что его спрашивают.Почему C++ STL-контейнеры используют оператор «меньше», а не «равный равный» оператор == в качестве компаратора?

Помимо вышеуказанного вопроса, также интересно узнать вкратце, как operator< будет работать для std::map.

Происхождение вопроса:

struct Address { 
    long m_IPv4Address; 
    bool isTCP; 
    bool operator< (const Address&) const; // trouble 
}; 
+2

Если '! (A jrok

+0

, если вы знаете, как сравнивать с '<', тогда все остальные могут быть сгенерированы. проверьте [здесь] (http://stackoverflow.com/q/23388739/4224575) –

+2

@jrok: Не обязательно. Они эквивалентны по отношению к упорядочению, но только равны, если согласуется определение 'operator =='. –

ответ

3

std::map<K,D> должен уметь сортировать. По умолчанию используется std::less<K>, для использования без указателей < .

Используя правило, что вы требуете как минимум вы можете от пользователей, синтезирует «эквивалентность» из <, когда ему это нужно (!(a<b) && !(b<a) означает a и b эквивалентны, то есть, ни меньше, чем другие).

Это упрощает создание классов для использования в качестве ключевых компонентов для map, что кажется хорошей идеей.

Есть std контейнеры, которые используют == такие как std::unordered_map, который использует std::hash и ==. Опять же, они спроектированы так, чтобы они требовали от своих пользователей меньше всего - вам не нужен полный заказ для контейнеров unordered_, просто эквивалент и хороший hash.

Как это бывает, очень легко написать <, если у вас есть доступ к <tuple>.

struct Address { 
    long m_IPv4Address; 
    bool isTCP; 
    bool operator< (const Address& o) const { 
    return 
     std::tie(m_IPv4Address, isTCP) 
     < std::tie(o.m_IPv4Address, o.isTCP); 
    } 
}; 

который использует std::tie определенные в <tuple> для создания надлежащего < для вас.std::tie берет кучу данных и генерирует tuple ссылок, которые имеют уже существующий <.


Для указателей, он использует некоторые сравнения, которые совместимы с <, где указано < поведения, и ведут себя хорошо, когда < нет. Это действительно имеет значение для сегментированной модели памяти и других неясных архитектур.

+0

Трюк std :: tie велик, это своеобразное элегантное решение, которое я искал. –

5

Поскольку std::map является отсортирован ассоциативный контейнер, это ключи необходимо упорядочивание.

== оператор не допустит, чтобы заказать несколько ключей

Вы могли бы искать std::unordered_map, что работа имеет Hashtable. Вы можете указать свои собственные хэш и оператор равенства функций:

explicit unordered_map(size_type bucket_count, 
        const Hash& hash = Hash(), 
        const KeyEqual& equal = KeyEqual(), 
        const Allocator& alloc = Allocator()); 
+0

То же самое верно для 'unordered_map'? – iammilind

+0

@iammilind: Нет, это использует хэш-функцию и сравнение равенства. –

+0

@iammilind: no, unordered_map похож на хэш-таблицу, mybe это то, что вы ищете? обновлено. – quantdev

2

С < вы можете заказать элементы. Если a < b, то a должен быть размещен до b в коллекции.

Вы также можете определить, являются ли два элемента эквивалентными: если !(a < b) && !(b < a) (если ни один объект не является меньшим, чем другой), то они эквивалентны.

Эти две возможности - все std::map. Поэтому он просто ожидает, что его тип элемента предоставит оператору <.

С == вы можете определить равенство, но вы не сможете заказать элементы. Поэтому он не будет удовлетворять требованиям std::map.

Смежные вопросы