std :: map不应该有重复的密钥,所以当我有自定义类型时它如何知道我有一个重复的密钥,我是否需要做重载重载运算符==?或者它将被隐式创建?
根据文件我只需要操作员<但这还不足以维持钥匙的独特性。
考虑这个例子:
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;
}
}
答案 0 :(得分:19)
std::map
并不关心密钥的文字 unicity 。它关心键等价。当a
和b
都不为真时,键a < b
和b < a
按定义是等效的。
另请注意,std::map
不会直接使用operator <
。 std::map
对operator <
一无所知。相反,std::map
使用比较谓词,其类型被指定为std::map
模板的第三个参数。该参数的默认值为std::less
。 std::less
的实施将比较委托给operator <
(除非有特殊的不同)。这就是operator <
发挥作用的方式。但是,您始终可以提供自己的谓词,但不一定使用operator <
。
但无论如何,关键时刻是std::map
使用了排序&#34; less&#34;比较而且只是&#34;较少&#34;比较。它不需要也不关心任何&#34;平等&#34;比较。
与此同时,std::unordered_map
将是另一回事。它依赖于非订购&#34;平等&#34;谓词指定的比较。默认情况下为std::equal_to
。 std::equal_to
的实施将对operator ==
的调用委托给代理(除非另有说明)。
答案 1 :(得分:3)
运营商&lt;足够。可以通过测试&lt;来检查平等性。 b和b&lt;两者都返回假。
答案 2 :(得分:2)
你应该重载operator<
。
std::map
将比较使用的密钥
!(a < b) && !(b < a)
作为对唯一性的考验。
答案 3 :(得分:2)
订单关联容器仅使用严格的弱订单来标识它们的键。他们不会使用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)