C++ 在std::map中更改值的键

C++ 在std::map中更改值的键,c++,dictionary,map,stl,key-value,C++,Dictionary,Map,Stl,Key Value,我需要为std::map中的给定值更改键。所以我写了这个方法: bool alter_key(_Kty oldKey, _Kty newKey) { std::map<_Kty, _Ty>::iterator it = this->find(newKey); if(it != end()) //can't replace because newKey is already been used. return false; it = th

我需要为std::map中的给定值更改键。所以我写了这个方法:

bool alter_key(_Kty oldKey, _Kty newKey)
{
    std::map<_Kty, _Ty>::iterator it = this->find(newKey);
    if(it != end()) //can't replace because newKey is already been used.
        return false;

    it = this->find(oldKey);
    if(it == end()) // empty index.
        return false;

    _Ty value = it->second;
    this->erase(it);
    this->insert(std::pair<_Kty, _Ty>(newKey, value));
    return true;
}
bool alter_key(_ktyoldkey,_ktynewkey)
{
std::map::iterator it=this->find(newKey);
if(it!=end())//无法替换,因为newKey已被使用。
返回false;
它=此->查找(旧键);
if(it==end())//空索引。
返回false;
_Ty值=它->秒;
这个->删除(它);
这个->插入(std::pair(newKey,value));
返回true;
}

它可以正常工作,但是否可以优化此代码?

如果需要加快特定的操作,那么对于容器来说,
std::map
可能不是正确的选择。也就是说,它可能也是正确的选择,因此下一个问题是,在该函数中有什么需要优化,函数中的较高成本是什么?这是查找吗?创建新元素的成本是多少

如果较高的成本是复制数据,那么您可能需要考虑在算法中避免复制。您可以跳过中间副本,而不是从容器复制到局部变量,然后执行额外的副本插入到目标:

insert(std::make_pair(new_key,it->value));
erase(it);
如果
值的复制成本很高,但可以移动(右值引用移动,或者默认构造成本很低,可以交换内容),则可以利用它:

insert(std::make_pair(new_key,std::move(it->value)));
// alternatively in C++03, for example for large strings or std::vector<> values
value_type& x = *insert(std::make_pair(new_key,ValueType())).first;
swap(x,it->value);
insert(std::make_pair(新的_键,std::move(it->value));
//或者在C++03中,例如对于大字符串或std::vector值
value_-type&x=*insert(std::make_-pair(new_-key,ValueType())。首先;
交换(x,it->value);
注意事情是如何变得更加复杂和难以理解/维护的

另一件可以改进的事情是查找。目前,您在容器中执行三次查找:两次查找以确定新旧密钥的存在,第三次查找以插入。你可以减少。如果尝试插入且密钥已存在,则不会修改该密钥,因此可以执行以下操作:

using std::swap;
iterator it = find(old_key);
if (it == end()) return false;
std::pair<bool, iterator> ins_res = insert(std::make_pair(new_key,ValueType()));
if (!ins_res.second) return false;
swap(it->second,ins_res.first->second); // swap contents
erase(it);
使用std::swap;
迭代器it=find(旧的_键);
if(it==end())返回false;
std::pair ins_res=insert(std::make_pair(new_key,ValueType());
如果(!ins_res.second)返回false;
交换(it->second,ins_res.first->second);//交换内容
抹去(它);

<>但是,还是考虑一下<代码> STD::MAP<代码>是您的数据结构的正确选择…例如,如果查找成本很高且排序不重要,则使用
std::unordered\u map
,因为它可能具有更好的查找性能。

您分析了应用程序并发现这是一个瓶颈?如果映射类型的复制成本很高,请将其设置为唯一/共享的\ptr。是的,这对速度至关重要,但不幸的是,我不是一个熟练的C++开发人员。那么,你所确定的瓶颈是什么?地图插入(没有什么地方可以使它更快)或者对象复制?如果对象不是指针,那么复制对象。非常感谢,但是对于我的任务来说,键的唯一性是重要的。@ USER 27 08147:唯一性从未被讨论过。顺序和唯一性不是一回事。
std::map
std::unordered_map
都提供了相同的唯一性保证,只是底层数据结构和复杂性有所不同。维护已排序的数据(如
std::map
)比保证唯一性更昂贵。再次感谢您,David!我在上读到了关于std::unordered_map的文章,这正是我所需要的。