2016-06-09 22 views
6

我在处理迭代时想知道std::unordered_multimap中关键对象的唯一性。我试图解释一下:我需要将一些数据与地图中的键类型关联起来,这些数据不应该在HashKeyEqual元素中考虑,但我需要它来避免存储单独的地图它(为了优化目的)。关于std :: unordered_multimap中关键唯一性的保证

因此,与我的想法相关的代码如下:

struct Key { 
    void* data; 
    mutable bool attribute; 

    Key(void* data) : data(data), attribute(false) { } 
    bool operator==(const Key& other) const { 
    return data == other.data; 
    } 
}; 

struct KeyHash { 
    size_t operator()(const Key& key) const { 
    return std::hash<void*>()(key.data); 
    } 
}; 

class Foo { 
public: 
    int i; 
    Foo(int i) : i(i) { } 
}; 

std::unordered_multimap<Key, Foo, KeyHash> map; 

问题的事实,虽然这工作得很好,没有任何有关的关键检索为第一要素的事实担保发生映射到单个元素的std::pair<const Key, Foo>始终是相同的。作为const Keypair这听起来像在地图上的每一个元素都有其通过值的密钥副本,这样,如果我做

void* target = new int(); 
map.emplace(std::make_pair(target, Foo(1))); 
map.emplace(std::make_pair(target, Foo(2))); 


auto pit = map.equal_range(target); 
pit.first->first.attribute = true; 
std::cout << std::boolalpha << (++pit.first)->first.attribute << endl; 

这就产生false这确认了我的心思。因此,如果您有多个具有相同密钥的值(因为您使用的是std::unordered_map,所以这是您想要的),所以浪费很多空间来存储密钥。

我没有看到任何其他的解决办法,而不是像

struct Value 
{ 
    std::vector<Foo> foos; 
    bool attribute; 
}; 

std::unordered_map<void*, Value> map; 

,让我配对的属性与关键,但让一切不干净的,因为它需要与迭代器的两个层面的工作。

我还没有看到其他解决方案吗?

+0

只需使用'boost :: multiindex' – Slava

+2

'map [target] = Foo(1);''std :: unordered_multimap'不会超载'operator []' –

+0

您的要求并不十分清楚。你是否在寻找像'std :: unordered_map >'这样的东西?这将愉快地将多个值与相同的密钥相关联,而不会复制密钥。 –

回答

2

23.5.5.1类模板unordered_multimap概述[unord.multimap.overview]

1所述的unordered_multimap是支持等价密钥( unordered_multimap的一个实例可以包含每个键值的多个副本的无序关联容器),并且将另一个 类型mapped_type的值与关键字相关联。 unordered_multimap类支持前向迭代器。

一个unordered_multimap可能含有关键的多个副本,如果你想关键的一个副本,然后一个潜在的unordered_map<K, vector<V>>可能更合适。