我有一个我定义了比较运算符的类。以下是我写的代码
#include <set>
#include <map>
#include <list>
template <typename _TyV>
class Element {
public:
Element(_TyV in) : m_Label(in){}
~Element() {}
bool operator < ( const Element & right) const {
return m_Label < right.m_Label;
}
private:
_TyV m_Label;
protected:
};
typedef Element<int> ElementType;
int main ( int argc, char **argv) {
std::set<ElementType> mySet;
for ( int i = 0; i < 10; i++) {
mySet.insert(ElementType(i));
}
std::map<ElementType*, std::list<ElementType*> > myMapList;
return 0;
}
我对std::map
的工作方式感到困惑,因为我对std::map
感兴趣的元素是指向ElementType
的指针。我真正想要的是将实际数据存储在std::set
中,并在std::map
less than operator
答案 0 :(得分:7)
您的地图std::map<ElementType*, std::list<ElementType*> >
正常使用密钥类型std::less
作为其比较器。
std::less
被定义为产生一致的排序,但排序仅基于地址,而不是基于它可能指向的任何内容。
因此,您的集合根据operator<
中的Element
对其内容进行排序,但地图会根据键的实际指针值对它们进行排序。这可能不是你想要的:(1)它使包含相同Element<int>
值的不同m_Label
对象充当地图中的不同键,(2)它表示地图将在来自集合的不同顺序。但std::map
可以使用额外的模板参数来提供比较器,因此您可以更改它。
您可以编写一个带两个指针的比较器,并比较它们指向的对象。这当然假设一旦你使用指针作为地图中的一个关键点,你就确保它所指向的对象(我假设在set
中),但如果没有,那么插入关于{的样板讲座{1}}这里)。由于shared_ptr
复制起来很便宜,因此使用Element<int>
代替ElementType
几乎肯定会更好。但是,如果ElementType*
仅代表您将来要使用的复制费用很高,那么请更改int
比较器。
您可能不关心map
中元素的顺序。如果你不这样做,并且你在map
中查找的唯一内容是指向map
中对象的指针,那么使用set
作为映射键而不指定比较器应该没事。