Как std :: map проверяет, что все указатели равны нулю?

Я реализую собственный класс карты, аналогичный классу из std, однако у меня есть одна проблема. На их карте, когда вы это делаете (например):

map<string, SomeObject*> container;
SomeObject* object = container["this doesn't exist"];

в объекте отладчика - 0x0000000, поэтому недопустимые значения из карты всегда равны нулю. Однако на моей карте недопустимые значения похожи на неинициализированные указатели - они имеют недопустимое значение, например 0xcdcdcdcd, однако в режиме выпуска это что-то еще, поэтому я не могу полагаться на проверку

if(object == 0xcdcdcdcd)

Итак, я хотел бы иметь возможность сделать это:

MyMap<string, SomeObject*> container;
SomeObject* object = container["this doesn't exist"]; //and for this to definetely be nullptr

так что я могу тогда сделать

if(object == nullptr)
   DoSomething();

У меня есть функция bool ContainsKey (KeyType key);, но она включает цикл for. Есть ли способ обеспечить то, что я хочу, во время инициализации для карты, или мне нужно сделать пользовательский PointerWrapper, который будет содержать указатель на SomeObject, для которого установлено значение nullptr в конструкторе PointerWrapper? У меня было трудно понять, что происходит в заголовках std, они содержат огромное количество макросов и определений типов.


person ulak blade    schedule 29.03.2013    source источник
comment
std::map<> значение-инициализирует свои значения - см. этот вопрос / ответ для стандартной версии.   -  person ildjarn    schedule 30.03.2013
comment
Типичный способ проверки ключа - это map :: find (key)! = Map :: end, а не проверка значения по умолчанию. stackoverflow.com/questions/2333728/stdmap-default-value имеет хорошее решение вашей проблемы.   -  person IdeaHat    schedule 30.03.2013


Ответы (3)


Ваши значения (для любого типа) будут инициализированы, если вы явно создадите объект

SomeObject* object = SomeObject*();
//                              ^^ Explicit construction

Для классов явно вызывается конструктор по умолчанию.

Для встроенных типов, таких как ints и указатели (например, SomeObject*), они будут инициализированы нулем (вместо неинициализированных)

Итак, хотя вы можете использовать = NULL в конкретном примере указателя, подобный синтаксис подойдет для всех типов.

template < typename Key, typename Value >
void MyMap<Key, Value> add_new_key( const Key &k )
{
   std::pair<Key, Value>( k, Value() );
//                                ^^ Either calls constructor or zero-initializes

   // Store the data as you wish...
}
person Drew Dormann    schedule 29.03.2013

std::map value инициализирует все новые значения, которые создает внутри. В случае скалярных типов это означает, что они инициализируются значением 0.

person Collin Dauphinee    schedule 29.03.2013

с std :: map, когда вы ссылаетесь на несуществующую запись, она создает ее и устанавливает для нее пустое значение. Для указателя это означает установку значения на null;

person pm100    schedule 29.03.2013