map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
Я озадачен, потому что не знаю, считал ли он поведение undefined или нет, как узнать, когда я запрашиваю ключ, который не существует, вместо этого я просто использую find?
map<string, string> dada;
dada["dummy"] = "papy";
cout << dada["pootoo"];
Я озадачен, потому что не знаю, считал ли он поведение undefined или нет, как узнать, когда я запрашиваю ключ, который не существует, вместо этого я просто использую find?
map::operator[]
выполняет поиск в структуре данных для значения, соответствующего данному ключу, и возвращает ссылку на него.
Если он не может найти один, он прозрачно создает для него построенный по умолчанию элемент. (Если вы не хотите этого поведения, вы можете использовать функцию map::at
.)
Вы можете получить полный список методов std:: map здесь:
http://en.cppreference.com/w/cpp/container/map
Вот документация map::operator[]
из текущего стандарта С++...
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.
Сложность: логарифмическая.
Если вы попытаетесь получить доступ к key value
с помощью оператора индекса []
, то могут произойти две вещи:
key
. Поэтому он вернет соответствующий key value
.key
. В этом случае он автоматически добавит key
к карте с помощью null value
. "pootoo"
ключ не существует на вашей карте. Поэтому он автоматически добавит этот key
с помощью value = ""
(пустая строка). И ваша программа напечатает пустую строку.
Здесь размер карты будет увеличен на 1
.
Для поиска ключа вы можете использовать map_name.find()
, который вернет map_name.end()
, если ключ не существует. И никакие дополнительные key
не будут добавлены.
Вы можете использовать оператор []
, если вы хотите установить значение для ключа.
Это не поведение undefined. Если operator []
не находит значение для предоставленного ключа, он вставляет его в эту позицию.
Для оператора [], если вы пытаетесь получить доступ к значению для ключа, который не существует, новый объект значения, который был сконструирован по умолчанию, будет помещен в карту и возвращается эта ссылка.
operator[]
для map
возвращает неконстантную ссылку, и вы можете назначить ее так, как показано на второй строке. Доступ таким образом создаст стандартный элемент value
по умолчанию.
Если вы хотите найти элемент поиска, лучший способ -
iterator find ( const key_type& x )
(или альтернатива const), которая вернет итератор, равный <map>.end()
, если он не найдет ключ, или просто хотите узнать, может ли он в коллекции использовать
size_type count ( const key_type& x ) const
который всегда будет возвращать 1 или 0 для карты, поскольку ключи уникальны.
Если оператор [] не находит значение для предоставленного ключа, он вставляет его в эту позицию.
Но вы должны заметить, что если вы посещаете 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;
пожалуйста, посмотрите на исключение 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