При использовании std:: map должен ли я перегрузить operator== для типа ключа?
у std::map не должно быть дублированных ключей, так как он знает, что у меня есть дублированный ключ, когда у меня есть пользовательский тип, мне нужно сделать перегрузку перегрузка operator==? Или он будет неявно создан?
согласно документации мне нужен только оператор
Рассмотрим пример:
class MyType{
public:
MyType(int newId){
id = new int;
*id = newId;
};
~MyType{
delete id;
}
private:
int* id;
};
int main(){
std::map<MyType,int> myMap;
std::pair<std::map<MyType,int>::iterator,bool> ret;
ret = myMap.insert ( std::pair<MyType,int>(myType(2),100) );
if (!ret.second) {//now how can he knows that?
std::cout << "element already existed" << endl;
}
}
4 ответов
std::map не заботится о буквальном уникальность ключи. Он заботится о ключах эквивалентности. Ключи!--1--> и b эквивалентны по определению, когда ни a < b, ни b < a - это правда.
обратите внимание также, что std::map напрямую не использует operator <. std::map ничего не знает о operator <. Вместо std::map использует предикат сравнения, тип которого указан в качестве третьего параметра std::map шаблон. Неисполнение значение этого параметра -std::less. Реализация std::less делегирует сравнение с operator < (если не специализировано по-разному). Вот как!--6--> вступает в игру. Но вы всегда можете предоставить тур собственный предикат, который не обязательно будет использовать operator <.
но в любом случае ключевым моментом здесь является то, что std::map использует сравнение заказа " меньше "и только сравнение" меньше". Он не нуждается и не заботится о каких-либо сравнениях "равенства".
между тем, std::unordered_map была бы другая история. Он опирается на неупорядоченное сравнение "равенства", указанное предикатом. По умолчанию это std::equal_to. Реализация std::equal_to делегирует вызов operator == (если специализировано по-разному).
вы должны перегрузить operator<.
на std::map будет сравнивать ключи с помощью
!(a < b) && !(b < a) как тест на уникальность.
ассоциативные контейнеры order используют только строгий слабый порядок для идентификации ключей. Они не будут использовать operator==(). Единственное сравнение, используемое для поиска объектов, - это третий аргумент шаблона std::map<K, V, Compare, Allocator>.
сравнение используется для группировки ключей в наборы эквивалентности. Два ключа k1 и k2 считаются эквивалентными, если ни k1 меньше, чем k2, ни k2 меньше, чем k1:
bool equivalent = !(k1 < k2) && !(k2 < k1);
конечно, ассоциативный контейнеры фактически будут использовать что-то вроде
!predicate(k1, k2) && !predicate(k2, k1)