Подтвердить что ты не робот

Что произойдет, если я прочитаю значение карты, где ключ не существует?

map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];

Я озадачен, потому что не знаю, считал ли он поведение undefined или нет, как узнать, когда я запрашиваю ключ, который не существует, вместо этого я просто использую find?

4b9b3361

Ответ 1

map::operator[] выполняет поиск в структуре данных для значения, соответствующего данному ключу, и возвращает ссылку на него.

Если он не может найти один, он прозрачно создает для него построенный по умолчанию элемент. (Если вы не хотите этого поведения, вы можете использовать функцию map::at.)

Вы можете получить полный список методов std:: map здесь:

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

Вот документация map::operator[] из текущего стандарта С++...

23.4.4.3 Доступ к элементу карты

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

  • Эффекты: Если в карте нет ключа, эквивалентного x, вставляет в карту значение_type (x, T()).

  • Требуется: key_type должен быть CopyConstructible, а mapped_type - DefaultConstructible.

  • Возвращает: ссылка на mapped_type, соответствующую x в * this.

  • Сложность: логарифмическая.

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

  • Эффекты: Если на карте нет ключа, эквивалентного x, вставляет в карту значение_type (std:: move (x), T()).

  • Требуется: mapped_type должен быть DefaultConstructible.

  • Возвращает: ссылка на mapped_type, соответствующую x в * this.

  • Сложность: логарифмическая.

Ответ 2

Если вы попытаетесь получить доступ к key value с помощью оператора индекса [], то могут произойти две вещи:

  • Карта содержит это key. Поэтому он вернет соответствующий key value.
  • Карта не содержит key. В этом случае он автоматически добавит key к карте с помощью null value.

"pootoo" ключ не существует на вашей карте. Поэтому он автоматически добавит этот key с помощью value = "" (пустая строка). И ваша программа напечатает пустую строку.

Здесь размер карты будет увеличен на 1.

Для поиска ключа вы можете использовать map_name.find(), который вернет map_name.end(), если ключ не существует. И никакие дополнительные key не будут добавлены.

Вы можете использовать оператор [], если вы хотите установить значение для ключа.

Ответ 3

Это не поведение undefined. Если operator [] не находит значение для предоставленного ключа, он вставляет его в эту позицию.

Ответ 4

Для оператора [], если вы пытаетесь получить доступ к значению для ключа, который не существует, новый объект значения, который был сконструирован по умолчанию, будет помещен в карту и возвращается эта ссылка.

Ответ 5

operator[] для map возвращает неконстантную ссылку, и вы можете назначить ее так, как показано на второй строке. Доступ таким образом создаст стандартный элемент value по умолчанию.

Если вы хотите найти элемент поиска, лучший способ -

iterator find ( const key_type& x )

(или альтернатива const), которая вернет итератор, равный <map>.end(), если он не найдет ключ, или просто хотите узнать, может ли он в коллекции использовать

size_type count ( const key_type& x ) const

который всегда будет возвращать 1 или 0 для карты, поскольку ключи уникальны.

Ответ 6

Если оператор [] не находит значение для предоставленного ключа, он вставляет его в эту позицию.

Но вы должны заметить, что если вы посещаете not exist key и вызываете его функцию-член, например mapKV [not_exist_key].member_fun(). Программа может завершиться сбоем.

Позвольте мне привести пример, тестовый класс, как показано ниже:

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;
    }
};

Тестовый код:

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;

Вывод, как показано ниже:

-------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

Мы видим, что: idName[5] вызывает конструкцию карты {5, MapValue(0)} для вставки в idName.

Но если вы вызываете функцию-член по idName[5], то программа вылетает:

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;

Ответ 7

пожалуйста, посмотрите на исключение out_of_range: http://www.cplusplus.com/reference/stdexcept/out_of_range/

это то, что map:: at и map:: operator [] будет выдавать, если ключ не существует. Вы можете поймать его так же, как векторный пример в ссылке.

Вы также можете использовать: http://www.cplusplus.com/reference/map/map/find/

И проверьте карту: end