Looking for right container

closed account (10oTURfi)
I need a map-like container in which 1 value could be accessed by multiple keys(usually dozen), which could be dynamically added/removed.
Would such thing hurt performance? Am I better off just using map of pointers in which multiple pointers point to same object?
How would the container you imagine behave differently than a map with multiple pointers to the same object?
closed account (10oTURfi)
Actually, on second thought... It probably wouldnt. I have no clue what I was thinking when I posted this question...
closed account (3TXyhbRD)
Think about this case:
3 keys: a, b, c and to each you assign a pointer that points to a dynamic variable. When I delete the value assigned to a (freeing the memory, because it's dynamically allocated), what would the assigned value for b and c point?

What your map-like container looks like is probably like this: for a value you can assign, not a single key, but a set of keys. By using this representation your performance won't be hurt because your search for a key will still take O(|K|), K being the actual key domain (a set of all keys that are being used at that moment).
closed account (10oTURfi)
Yes! That was it. Thanks for reminding me.

By now i assume such container doesnt exist. Guess i should write one...
The boost library has multi-index containers: http://www.boost.org/doc/libs/release/libs/multi_index/doc/index.html , although it doesn't support dynamic addition/removal of keys.

If you really want that (even if you want to write your own), look into databases.
Last edited on
closed account (3TXyhbRD)
You can use an ordinary map where your key is actually a set and override the equal and not equal operators to search for a key in the set.
Using an existing set from which you derive and add the functions you need will be the fastest way to go.
you could use map<vector</*the type of your keys*/>, /*the type of your values*/>
An unordered_map of keys to pointers seems to be the right solution. If you want object sharing, use shared_ptrs. Really, why complicate things?

If you use vectors or sets as keys, you won't be able to search on keys.
Multiindex container and databases are overkill. It would be slower, heavier and you wouldn't use most of the functionality.
closed account (10oTURfi)
I just wrote this one. Not sure if its best idea, but what do you guys think?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include <iostream>
#include <vector>
#include <string>
using namespace std;

template<class K, class T>
class map
{
    struct Node
    {
        std::vector<K> vKeys;

        T data;
        Node* pNext;
    };

    Node* pFirst;
public:

    map()
    {
        pFirst = NULL;
    }
    ~map()
    {
        Node* pTemp;
        while(pFirst)
        {
            pTemp = pFirst;
            pFirst = pFirst->pNext;
            delete pTemp;
        }
    }
    T& operator[](K key)
    {
        if(!pFirst)
        {
            pFirst = new Node;
            pFirst->vKeys.push_back(key);
            pFirst->pNext = NULL;
            return pFirst->data;
        }
        Node* pIter = pFirst;
        Node* pTemp;
        while(pIter)
        {
            pTemp = pIter;
            for(unsigned i=0; i<pIter->vKeys.size(); ++i)
            {
                if(pIter->vKeys[i] == key)
                    return pIter->data;
            }
            pIter = pIter->pNext;
        }
        pIter = new Node;
        pIter->pNext = NULL;
        pIter->vKeys.push_back(key);
        pTemp->pNext = pIter;
        return pIter->data;
    }
    /*
    Note that T is always a pointer, 
    but that is not the case in this dummy example
    */
    void add_key(T where, K key)
    {
        Node* pIter = pFirst;
        while(pIter)
        {
            if(pIter->data == where)
            {
                pIter->vKeys.push_back(key);
                return;
            }
            pIter = pIter->pNext;
        }
        throw "This shouldn't happen";
    }
};

int main()
{
    map<int, string> m;

    m[5] = "foo";
    m[15] = "bar";
    m.add_key("foo", 14);

    cout << m[14] << endl << m[15];

    cin.get();
}
Last edited on
Topic archived. No new replies allowed.