What happens if I read a map's value where the key does not exist?

前端 未结 7 1094
孤独总比滥情好
孤独总比滥情好 2020-12-05 12:24
map dada;
dada[\"dummy\"] = \"papy\";
cout << dada[\"pootoo\"];

I\'m puzzled because I don\'t know if it\'s considered

相关标签:
7条回答
  • 2020-12-05 12:58

    The operator[] for map returns a non-const reference and you can assign using that in the way you've shown on your second line. Accessing in this way will create a default contructed element of value type.

    If you want to find a find an element, a better way is

    iterator find ( const key_type& x )
    

    (or the const alternative) which will return an iterator equal to <map>.end() if it doesn't find the key, or if you just want to know if it's in the collection you can use

    size_type count ( const key_type& x ) const
    

    which will always return either 1 or 0 for a map since keys are unique.

    0 讨论(0)
  • 2020-12-05 13:02

    For operator[], if you try to access a value for a key that doesn't exist, a new value object that has been default constructed will be put into the map and it's reference returned.

    0 讨论(0)
  • 2020-12-05 13:03

    It's not undefined behavior. If operator [] doesn't find a value for the provided key, it inserts one at that position.

    0 讨论(0)
  • 2020-12-05 13:09

    If operator [] doesn't find a value for the provided key, it inserts one at that position.

    But you should note that if you visit a not exist key and invoke it's member function, like mapKV[not_exist_key].member_fun().The program may crash.

    Let me give an example, test class as below:

    struct MapValue{
        int val;
    
        MapValue(int i=0){
            cout<<"ctor: "<<i<<endl; val = i;
        }
    
        ~MapValue(){
            cout<<"dtor: "<<val<<endl;
        }
    
        friend ostream& operator<<(std::ostream& out, const MapValue& mv){
            cout<<"MapValue: "<<mv.val<<endl;
        }
    
        string toString(){
            cout<<"MapValue: "<<val<<endl;
        }
    };
    

    Test code:

    cout<<"-------create map<int, MapValue>-------"<<endl;
    
    map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
    
    cout<<"-----cout key[2]-----"<<endl;
    cout<<idName[2]<<endl;
    
    cout<<"-----cout key[5]-----"<<endl;
    cout<<idName[5]<<endl;
    
    cout<<"------- runs here means, does't crash-------"<<endl;
    

    Output as below:

    -------create map<int, MapValue>-------
    ctor: 1
    ctor: 2
    dtor: 2
    dtor: 1
    dtor: 2
    dtor: 1
    -----cout key[2]-----
    MapValue: 2
    
    -----cout key[5]-----
    ctor: 0
    MapValue: 0
    
    -------runs here means, does't crash-------
    dtor: 0
    dtor: 2
    dtor: 1
    

    We can see that: idName[5] invoke map construct {5, MapValue(0)} to insert to idName.

    But if, you invoke member function by idName[5], then the program crashes :

    cout<<"-------create map<int, MapValue>-------"<<endl;
    
    map<int, MapValue> idName{{1, MapValue(1)}, {2, MapValue(2)}};
    
    
    idName[5].toString();  // get crash here.
    
    
    cout<<"------- runs here means, doesn't crash-------"<<endl;
    
    0 讨论(0)
  • 2020-12-05 13:13

    If you try to access a key value using index operator [], then 2 things can happen :

    1. The map contains this key. So it will return the corresponding key value.
    2. The map doesn't contain the key. In this case, it will automatically add a key to the map with null value.

    "pootoo" key does't exist in your map. So it will automatically add this key with value = ""(empty string). And your program will print empty string.

    Here map size will increase by 1.

    To search a key you can use map_name.find(), which will return map_name.end() if the key doesn't exist. And no extra key will be added.

    You can use [] operator when you want to set value for a key.

    0 讨论(0)
  • 2020-12-05 13:19

    The map::operator[] searches the data structure for a value corresponding to the given key, and returns a reference to it.

    If it can't find one it transparently creates a default constructed element for it. (If you do not want this behaviour you can use the map::at function instead.)

    You can get a full list of methods of std::map here:

    http://en.cppreference.com/w/cpp/container/map

    Here is the documentation of map::operator[] from the current C++ standard...

    23.4.4.3 Map Element Access

    T& operator[](const key_type& x);

    1. Effects: If there is no key equivalent to x in the map, inserts value_type(x, T()) into the map.

    2. Requires: key_type shall be CopyConstructible and mapped_type shall be DefaultConstructible.

    3. Returns: A reference to the mapped_type corresponding to x in *this.

    4. Complexity: logarithmic.

    T& operator[](key_type&& x);

    1. Effects: If there is no key equivalent to x in the map, inserts value_type(std::move(x), T()) into the map.

    2. Requires: mapped_type shall be DefaultConstructible.

    3. Returns: A reference to the mapped_type corresponding to x in *this.

    4. Complexity: logarithmic.

    0 讨论(0)
提交回复
热议问题