Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::初始化后映射更改键\u comp_C++_Stl_Stdmap - Fatal编程技术网

C++ std::初始化后映射更改键\u comp

C++ std::初始化后映射更改键\u comp,c++,stl,stdmap,C++,Stl,Stdmap,在创建和初始化std::map之后,是否可以更改其比较方法? 或者可能只有在它被创建之后 我想以某种方式改变一个类的行为,该类包含一个我无法更改定义的映射。我想通过传递另一个映射来更改它的比较行为。可能是有可能的,这是未经测试的: 定义您自己的自定义比较器,它在内部有一个指向比较函数实际实现的指针 将此实例传递给映射的构造函数(也必须使用此比较器键入映射) 稍后(在使用映射之前)设置真正的实现,如果在之后设置,则不知道对内部的影响 已经过测试,可以执行上述操作,但是如果树中有项目,则更改比较函数

在创建和初始化std::map之后,是否可以更改其比较方法? 或者可能只有在它被创建之后


我想以某种方式改变一个类的行为,该类包含一个我无法更改定义的映射。我想通过传递另一个映射来更改它的比较行为。

可能是有可能的,这是未经测试的:

  • 定义您自己的自定义比较器,它在内部有一个指向比较函数实际实现的指针
  • 将此实例传递给映射的构造函数(也必须使用此比较器键入映射)
  • 稍后(在使用映射之前)设置真正的实现,如果在之后设置,则不知道对内部的影响
  • 已经过测试,可以执行上述操作,但是如果树中有项目,则更改比较函数可能会带来灾难性后果


    无论如何,这听起来太可疑了……

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

    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());
    
    boolc1(常数K&,常数K&);
    布尔C2(常数K&,常数K&);
    标准::地图来源;
    ....
    std::映射可选项(orig.begin(),orig.end());
    
    不可能,因为它是通过模板参数编译到映射中的

    请参阅:比较是您要寻找的

    你想干什么

    由于您手中有一个用作键的类,因此可以实现<运算符或compare函数来响应上下文。由于可以将完全构造的对象传递给as比较函数,因此应该可以传递所有内容以实现上下文相关的功能。问题是,你为什么要这么做


    在std::map运行时更改其比较是一个坏主意,因为这将导致未定义的行为。仅仅基于std::map的内容是“排序的”(可能是RB树)这一事实。如果你改变了排序函数,你会突然改变逻辑顺序;但地图不会神奇地重新排列自己。下一次调用insert或find可能不会达到您预期的效果。

    不,这是不可能的。比较器是映射类型的一部分。这个问题与询问是否可以将
    int
    更改为存储浮点数没有什么不同

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

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

    或者,您可以创建第二个类型为
    std::map
    的映射,并使用原始映射的引用填充它,但按照
    Comp2
    排序。在这种情况下,您自己负责保持两个地图同步。像Boost.Multiindex这样的高级容器可以安全地为您执行此操作。

    您是否看到了一个函数,可以直接执行此操作:?如果不是,那么答案是否定的……它是一个模板参数,因此必须在编译时修复。改变它会改变容器的类型。没关系。映射是空的。@djWann我认为每次通过函数指针调用compare的开销会大大降低
    map
    操作的速度,如果您关心这个问题的话。@djWann如果映射是空的,为什么不使用一个新的呢?两个完全不同的对象,或者只要比较器是相同的签名:
    my\u map=std::map(&new\u compare)