2016-04-14 3 views
-3

Я новичок в C++ и имеют простую программу, как показано нижеПочему карта создавать новые записи с оператором []

#include <iostream> 
#include <map> 
#include <vector> 

using namespace std; 

int main() 
{ 
std::map<std::string, double*> testMap; 
std::vector<std::string> v = {"A", "B", "C"}; 
for(size_t i=0;i<v.size();++i) 
{ 
    std::string sym = v[i]; 
    double* d = testMap[sym]; 
    if(!d) continue; 
    cout << "this"; 
} 
for(std::map<std::string, double*>::iterator itr=testMap.begin();itr!=testMap.end();++itr) 
{ 
    cout << itr->first << " " << itr->second << std::endl; 
} 

return 0; 
} 

и его O/P является

sh-4.3$ main                                     
A 0                                       
B 0                                       
C 0 

Мой вопрос, почему карта создает новые элементы с нулевыми указателями двойных

+0

, потому что это то, что он делает, когда элемент не существует: http://en.cppreference.com/w/cpp/container/map/operator_at так дефолт к нулевому указателю в этом случае, вы объявили пустую карту, но затем попытаетесь получить доступ к элементам в местах, которые не существуют – EdChum

+1

Что вы ожидаете от этого? –

+1

Я подозреваю, что вы думаете, что он должен вести себя как элемент 'find'' std :: map', который возвращает конечный итератор при сбое в локализации. Если это поведение, которое вы хотите, то это функциональность, которую вы должны использовать; не 'operator []'. – WhozCraig

ответ

4

Это ожидаемое поведение std::map::operator[]:

Возвращает ссылку на значение, которое отображается на ключ, эквивалентный ключу , выполняя вставку, если такой ключ еще не существует.

Если вставка выполнена, отображаемое значение инициализируется значением (по умолчанию построено для типов классов, с нулевой инициализацией в противном случае) и возвращается ссылка на него.

Для double* нулевое инициализированное значение является нулевым указателем.

Вы можете изменить значение вставленный std::map::operator[]:

testMap[sym] = ...something...; 

или указать ключ и значение по std::map::insert:

testMap.insert({sym, ...something...}); 
1

Когда вы пишете testMap[sym] проверка делается, существует ли sym на карте, и если это произойдет, то ссылка на него будет возвращена. Если это не так, то новое начальное значение инициализируется в карту с ключом sym, в вашем случае это нулевой указатель.

Так что, если вы не хотите иметь нулевой Воулс, а затем проверить, если ключ существует с std::map::find, и сравните std::map::end(), вместо того, чтобы использовать std::map::operator[]

Мой вопрос, почему карта создает новые элементы с нулевыми двойными указателями

это как стандарт определяет поведение std::map::operator[]

n4140 23.4.4.3 map.access

T & оператор [] (const key_type & x);

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

и:

Т & оператор [] (key_type & & х);

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

0

То, как работают карты. На карте должно быть указано, действительно ли ключ опасен. Используйте для этого поиск (ключ). В вашем примере testmap [sym]; создает новую запись.

std::map<std::string,double*>::iterator it; 
it = testMap.find("A"); 
if (it == testMap.end()) 
{ // create a new entry 
    testMap["A"] = new double(1.0); 
} 

Match потеха Хилько

Смежные вопросы