Хотя адрес s не меняется (переменные не могут делать это в c ++), содержимое строки может измениться (например, указатель из s.c_str ()), поэтому будьте осторожны при игре с такими вещами .
map<pair<const char*, const char*>, string&> m;
Я бы посчитал такую конструкцию очень опасной, я предполагаю, например, что вы ожидаете, что ключ будет искать сравнения, основанные на строке, а не на расположении строк (т. Е. Значения Пуитнера).
Однако, игнорируя ваш выбор ключа, то, что вы делаете со значением m_tmp, является безопасным и хорошо определенным (то есть изменение одного изменит другой, потому что есть обе «одинаковые» переменные), при условии, что «string m_tmp;» не выходит из области видимости (или иным образом удаляется), а затем вы пытаетесь получить к нему доступ через карту (поскольку она больше не ссылается на действительную память).
Например, следующее небезопасно.
std::map<int, string &> myMap;
void foo()
{
string s = "Hello World";
myMap[5] = s;
}
int main()
{
foo();
//string s was destroyed when foo() returned, so myMap[5] is no longer a valid reference,
//so it is not defined what will happen here, hopefully an access violation
//rather than some obscure bug because the stack/heap got corrupted
std::cout << myMap[5] << std::end;
}
Стоит также отметить, что вы можете сделать это наоборот, опять же при условии, что элемент, с которого вы получили ссылку, не будет удален (однако это единственный раз, когда std :: map разрешается делать недействительной ссылку или итератор) .
std::map<int,string> myMap;
myMap[5] = "x";
string &s = myMap[5];//get a referecnce
myMap[5] = "Foo";
std::cout << s << std::end;//print Foo
s = "Bar";
std::cout << myMap[5] << std::endl;//print Bar