2012-12-18 67 views
5

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

我想改变一个包含我无法更改定义的映射的类的行为。我想通过传递另一张地图来改变它的比较行为。

+0

您是否在此处看到一个函数以允许您直接执行此操作:http://en.cppreference.com/w/cpp/container/map?如果不是,那么答案是否定的... – Nim

+2

这是一个模板参数,所以它必须在编译时修复。改变它会改变容器的类型。 – v154c1

回答

4

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

  1. 定义自己的比较,其内部有一个指针指向真正落实比较功能
  2. 的传递了这样的一个实例的构造地图(你必须使用这个比较器输入地图)
  3. 设置真正的实现后(使用地图之前),如果你设置它后,你不知道内部的影响...

已测试,并且可以做上面的,但是改变比较功能如果在树中的项目可能是灾难性的......

反正 - 这一切听起来太腥....

+0

没关系。地图是空的。 – djWann

+0

@djWann我认为每次通过函数指针调用比较的开销会显着减慢'map'操作,如果你关心的话。 – rici

+0

@djWann如果地图是空的,为什么不使用一个新的?要么是两个完全不同的对象,要么只要比较器是相同的签名:'my_map = std :: map <...>(&new_compare);' – rioki

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()); 
1

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

请参阅:http://www.cplusplus.com/reference/map/map/比较是你在找什么。

你想做什么?

既然您掌握了您正在用作Key的类,则可以实现<运算符或比较函数以对上下文作出反应。由于您可以将完全构建的对象作为比较函数传递给constructor,因此应该可以将所有内容都传递给实现依赖于上下文的同情。问题是,你为什么要?

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

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这样的高级容器可以以安全的方式为您做到这一点。

相关问题