初始化后std :: map更改key_comp

时间:2012-12-18 14:38:23

标签: c++ stl stdmap

在创建和初始化std :: map之后,可以更改它的比较方法吗? 或者也许只有在它被创建之后?

我想以某种方式改变包含我无法更改定义的地图的类的行为。我想通过传递另一张地图来改变它的比较行为。

4 个答案:

答案 0 :(得分:4)

也许这是可能的,这是未经测试的:

  1. 定义您自己的自定义比较器,其内部具有指向比较函数的实际实现的指针
  2. 将此实例传递给地图的构造函数(您还必须使用此比较器键入地图。)
  3. 稍后设置实际的实现(在使用地图之前),如果你之后设置它,你不知道对内部的影响......
  4. 已经过测试,并且可以执行上述操作,但是如果树中有项目则更改比较功能可能是灾难性的...

    无论如何 - 一切听起来都太可疑了......

答案 1 :(得分:2)

不,那是不可能的。比较器是地图的类型的一部分。问题与询问是否可以更改int以存储浮点数无关。

更重要的是,比较器提供的排序是地图内部结构的组成部分。如果要更改排序,则数据结构将不再处于一致状态。唯一可行的选择是从旧地图的元素重建新地图的新地图,但这已经成为可能:

std::map<T, V, Comp1> m1 = /* ... */;
std::map<T, V, Comp2> m2(m1.begin(), m1.end());

或者,您可以制作第二个std::map<std::reference_wrapper<T const>, std::reference_wrapper<V>, Comp2>类型的地图,并使用对原始地图的引用填充它,但是会根据Comp2进行排序。在这种情况下,您自己有责任保持两个地图同步。像Boost.Multiindex这样的高级容器可以安全地为您完成此任务。

答案 2 :(得分:1)

这是不可能的。但是您可以使用备用比较条件创建一个新映射,并使用第一个元素创建两个迭代器构造函数来实例化映射。

bool  C1(const K&, const K&);
bool  C2(const K&, const K&);

std::map<K, V, C1> orig;
....
std::map<K, V, C2> alternative(orig.begin(), orig.end());

答案 3 :(得分:1)

不可能,因为它通过模板参数编译到地图中。

请参阅:http://www.cplusplus.com/reference/map/map/ 比较是您正在寻找的。

你想做什么?

由于您使用的是手中的类,因此您可以实现&lt;运算符或比较函数以响应上下文。由于您可以将完全构造的对象作为比较函数传递给constructor,因此应该可以传递所有内容以实现依赖于上下文的同情。问题是,你为什么要这样做?

在运行时更改std :: map的比较是一个坏主意,因为它会导致未定义的行为。简单地基于std :: map的内容是“已排序”的事实(可能是RB树)。如果更改排序功能,您将突然改变逻辑顺序;但地图不会神奇地重新排序。下一次插入或查找的调用可能不会达到预期效果。