2016-10-07 3 views
0

Я новичок в области C++ и смущен о жизни std::string, когда он вставлен в std::map.Объем std :: string при наложении на карту

Например:

void loadMap(std::map<string, int> &myMap) 
{ 
    int num = rand(); 
    myMap[to_string(num) + "_xyz"] = num; 
} 

void main(int argc, char** argv) 
{ 
    std::map<string, int> myMap; 
    loadMap(myMap); 

    //Is the entry I just added to the map in loadMap still safe in there? 
    //i.e., is the key, which is an std::string, still around? 
    //Or its lifetime's ended? 
} 

Я сделал некоторые испытания и КАЖЕТСЯ быть в порядке, но я не уверен, если это будет всегда так. Может быть, мне просто повезло, что память, в которой была std :: string, не была затронута.

+0

Срок службы содержимого карты совпадает с временем жизни карты. – molbdnilo

+0

@Treycos Я понимаю, что 'loadMap' модифицировал карту DIRECTLY, потому что я прошел по ссылке, НО что, если срок жизни строки закончился? – 0x56794E

+0

Ответ выше – Treycos

ответ

2

Следующая операция создаст std::string RValue

to_string(num) + "_xyz" 

Поскольку Key типа для map является std::stringпо значению, этот Rvalue эффективно будут перемещены в карту. В этом случае вы в безопасности. Теперь карта «владеет» этой строкой. Поэтому время жизни строки совпадает с временем жизни на карте в main

+0

Хорошо. Круто! Спасибо за быстрый ответ SUPER! – 0x56794E

+0

_ "Следующая операция создаст ссылку std :: string && rvalue" _ Нет, она не будет. Он создаст 'std :: string' ([без ссылок] (http://en.cppreference.com/w/cpp/string/basic_string/operator%2B)), и выражение будет иметь категорию rvalue. Остальное верно. –

+0

@LightnessRacesinOrbit Моя ошибка, вы правы – CoryKramer

1

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

Если посмотреть на std::map::operator[], вы увидите, что ключ либо должен быть:

  • CopyConstructible в случае, если пара ключ/значение для этого ключа не существует (и/или ключ не может быть перемещен)
  • MoveConstructible в случае, когда ключ может быть перемещен, без внесения каких-либо копий

Это есть причина: контейнер будет копировать (или переместить) кнопку, чтобы сохранить его. Он не будет хранить указатель или ссылку, если ключ не существует.

То же самое относится и к значению: это ссылка на значение уже хранится на карте, и поэтому, когда вы делаете

myMap[to_string(num) + "_xyz"] = num; 

вы копируете num к внутреннему значению контейнера.

+1

Копия здесь крайне маловероятна. –

+0

@LightnessRacesinOrbit Right :) Спасибо – Rakete1111

+0

О, и 'CopyConstructible' не так; вам нужно посмотреть определение # 2 –