map键类必须满足哪些要求才能成为有效的键
What requirements must std::map key classes meet to be valid keys?
我想把一个给定类的对象映射到另一个类的对象。但是,我要用作键的类不是我编写的,它是一个具有几个值的简单struct
。std::map排序它的内容,我想知道它是如何做到的,如果任何任意类可以用作键,或者是否有一组需要定义的需求(操作符等)。
如果是这样,我可以为实现操作符映射使用的类创建一个包装器。我只需要知道我首先需要实现什么,并且我在网上找到的类的引用都没有指定它们。
所需要的键是可复制和可分配的。类的第三个参数定义映射中的顺序模板(以及构造函数的实参,如果使用的话)。这默认为std::less<KeyType>
,默认为<
操作符;但是不要求使用默认值。写一个比较操作符(最好作为函数对象):
struct CmpMyType
{
bool operator()( MyType const& lhs, MyType const& rhs ) const
{
// ...
}
};
注意它必须定义一个严格的顺序,即如果CmpMyType()( a, b
)
返回true,那么CmpMyType()( b, a )
必须返回false,如果都返回false,这两个元素被认为是相等的
需要定义操作符<,例如:
struct A
{
int a;
std::string b;
};
// Simple but wrong as it does not provide the strict weak ordering.
// As A(5,"a") and A(5,"b") would be considered equal using this function.
bool operator<(const A& l, const A& r )
{
return ( l.a < r.a ) && ( l.b < r.b );
}
// Better brute force.
bool operator<(const A& l, const A& r )
{
if ( l.a < r.a ) return true;
if ( l.a > r.a ) return false;
// a are equal, compare b
return ( l.b < r.b );
}
// This can often be seen written as
bool operator<(const A& l, const A& r )
{
// This is fine for a small number of members.
// But I prefer the brute force approach when you start to get lots of members.
return ( l.a < r.a ) ||
(( l.a == r.a) && ( l.b < r.b ));
}
答案实际上在你链接的参考中,在"Compare"模板参数的描述下。
唯一的要求是Compare
(默认为less<Key>
,默认使用operator<
来比较键)必须是"严格弱排序"
与set
相同:类必须按照"小于"的精神严格排序。要么重载一个适当的operator<
,要么提供一个自定义谓词。任意两个对象a
和b
,且!(a<b) && !(b>a)
被认为是相等的
map容器实际上将按照该排序提供的顺序保留所有元素,这就是您如何通过键值实现O(log n)查找和插入时间的方法。
相关文章:
- C++程序在将 int 与 cin 一起使用时有效,但不能使用字符串
- 是什么使这个以'+'开头的字符串添加成为有效的语句?
- 为什么不能提升::hana::overload_t成为类的成员
- C++:不能使运算符<<成为模板嵌套类的好友
- 为什么我不能使私人运营商成为新的并使用默认实现?
- 如果 null 不是有效值,则使参数成为引用而不是指针
- C++:为什么'this'不能成为 nullptr?
- 不能使外部类成为内部类内的成员对象
- OpenGL不能成为一个完美的立方体
- 为什么 decltype 在这里有效但不能自动?
- 为什么Main不能成为ConstexPr
- SDL_DISPLAYFORMAT有效,但不能进行SDL_DISPLAYFORMATALPHA
- 'int main(int argc, char* argv<::>)' 如何成为 main 的有效签名?
- 使用boost multiprecision/mpfr float-字符串不能被解释为有效的整数错误
- 如果 npos 为 -1,size_type怎么能成为无符号积分
- “f();”怎么能成为下面的声明
- leetcode中的最大数字:有人能解释为什么这个方法有效吗
- C++ - 检查指针是否指向有效内存(此处不能使用 NULL 检查)
- map键类必须满足哪些要求才能成为有效的键
- 如何查找不能成为 Unicode 字符串中单词一部分的字符