调整常量映射键

Tweaking const map key

本文关键字:映射 常量 调整      更新时间:2023-10-16

我想使用STL映射,其中的键在逻辑上是恒定的(使用映射的代码确保不会违反键排序),但实际上是作为变量实现的。例如,

struct K { int ka, kb; };
struct my_less : std::less<K> {
    bool operator()(const K& l, const K& r) const
        { return l.ka+l.kb < r.ka+r.kb; }
};
std::map<K, int, my_less> m;
// put something into m and now modify keys
K& k = *const_cast<K *>(&m.begin()->first);
k.ka++;
k.kb--;  // I skip code for verifying logical key immutability for the sake of example simplification

它可以工作(地图排序没有被破坏),但看起来很难看。还有更好的选择吗?

带指针的额外间接寻址(指针使常量而不使数据常量)是可能的,但它会增加开销(并增加不必要的复杂性)。

将可变键部分从键移动到值对我来说不是一个选项。

你不能巧妙地编辑地图的键是有充分理由的——你真的不应该这么做!在您的情况下,它可能不会破坏地图排序,但这并不能保证!(想想如果你修改两个密钥以具有相同的ka和kb值会发生什么?)

正确的方法是从地图中删除元素,然后用新键重新插入。

std::map<K, int, my_less> m;
// Push our starting object into the map
K key;
key.ka = 42;
key.kb = 123;
m[key] = 1234;
// Get the first element
auto iter = m.begin();
// make a new key
K key2;
key2 = iter->first;
key2.ka++;
key2.kb--;
int value = iter->second;
// remove old value
m.erase(iter);
// insert new value
m[key2] = value;

boost::multi_index对于这种情况是一个合理的替代方案。它支持在没有太多开销的情况下保持更改的顺序。