[C++] Best way to add and edit a map

Aug 5, 2013 at 4:20am
I have a map that I need to add and edit data. The problem is that I don't always know if I'm adding or editing.

As I understand, the .insert() function fails when the key already exists, and the [] operator will either insert or edit, depending whether or not it exists.

My question is twofold:
At the points where I know I'm inserting, is either method better?

At the pints where I don't know, is it better to use find and insert or use the [] operator, or is it just as well to just use the [] operator, and let the backend do the work?

Obviously, just using [] would be shorter, and logically (In my mind) faster, but my logic doesn't always match the STL, so I figured I should ask.

Thanks!
Aug 5, 2013 at 4:31am
Last edited on Aug 5, 2013 at 4:39am
Aug 5, 2013 at 4:52am
The only time (that I can think of) where operator[] can be useful is when you want to set the value of a key (overwrite it if it already has a value), and you know that it is safe to overwrite


That is my exact situation. The keys are user inserted, i.e they enter a key, and then the program asks for the value. So using the [] operator is a good, safe way for me to do it? I have no concerns for overwriting data.
Aug 5, 2013 at 5:43am
Hi meesa,

I have no idea whether this is relevant at all, but the last post where I mentioned the operator[], it was this example I had in mind :

http://www.cplusplus.com/forum/general/91237/#msg490444


So this problem was about recording the positions of words in a file. A map of vectors was used, the word is the key, and it's position the value pushed into the vector. The operator[] was convenient because if it was an existing word, then the position of it would be pushed into the vector for that key, otherwise the [] would return a new key and the word's position pushed into it's vector.

So it might depend on what the type of the map value is: POD; a class object; or a container; or combinations of these. And what the meaning (or consequences) of a duplicate map key is.

There is also std::multimap, std::unordered_map, and the idea that you can overload you own operator[] .

Any way I am sure you can figure all this out, it's just that there are different ways (of varying complexity) of thinking about it.

Last edited on Aug 5, 2013 at 5:44am
Aug 5, 2013 at 8:16am
So using the [] operator is a good, safe way for me to do it? I have no concerns for overwriting data.
Then the answer is clearly yes.

use insert() if you're interested in more than just putting the object in the map
Aug 5, 2013 at 10:05am
std::map<>::operator[]() requires that the mapped_type must be DefaultConstructible. If the key does not exist, it creates a key-data pair by default constructing the mapped_type, inserts the key-data pair into the map, and then returns a reference to the default constructed data.

std::map<>::emplace() allocates the requisite amount of memory and then constructs the key-data pair in-place.

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
#include <iostream>
#include <string>

struct A
{
    A() { std::cout << "A:: default constructor\n" ; }

    A( const char* aa ) : a(aa) { std::cout << "A:: one arg constructor\n" ; }

    A ( const A& that ) : a(that.a) { std::cout << "A:: copy constructor\n" ; }

    A& operator= ( const A& that )
    {
        std::cout << "A:: assignment\n" ;
        a = that. a ;
        return *this ;
    }

    std::string a ;
};

#include <map>

int main()
{
    std::map< int, A > map ;

    {
        // possibly only if A is DefaultConstructible
        map[1] = "hello world" ;
        /*
        A:: one arg constructor
        A:: default constructor
        A:: assignment
        */
    }
    std::cout << "------------------------\n" ;
    {
        // possibly only if A is CopyConstructible
        map.insert( { 2, "hello again" } ) ;
        /*
        A:: one arg constructor
        A:: copy constructor
        */
    }
    std::cout << "------------------------\n" ;
    {
        map.emplace( 3, "hello for a third time" ) ;
        // A:: one arg constructor
    }
}

http://ideone.com/iqxyzf
Aug 6, 2013 at 1:57am
My map is simply map<char, float>. I'll be using the [] operator where I'm not sure.

Thanks to everybody for the input!
Topic archived. No new replies allowed.