Although the address of s does not change (variables are not allowed to do that in c++), the contents of the string may change (eg the pointer from s.c_str()) so be careful when playing with stuff like that.
map<pair<const char*, const char*>, string&> m;
Id consider a construct like that very dangerous, I assume for example that you expect the key to look for comparisons based on the string, not the location of the strings (ie the poitner values).
However ignoring your choice of key, what your doing with the m_tmp value is safe and well defined (that is changing one will change the other, because there both the "same" variable), providing that the "string m_tmp;" does nto go out of scope (or otherwise deleted) and then you try to access it through the map (since it is no longer referencing valid memory).
Eg the following is not safe.
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;
}
Its also worth noting that you can do it the other way around, again providing that the element you got a reference from is not erased (however thats the only time an std::map is allowed to invalidate a reference or iterator).
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