Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a reference to data held by boost::any

I've got a map of any pointers, called gmap, defined like so:

std::map<std::string, boost::any*>& gmap = getSingleton().globalValues;

This map is indeed a reference to globalValues, I've checked the addresses in gdb. I've also got control of the any pointers (which is why they are pointers, I'd rather do references, but I'm debugging right now). Now, then I return this in the same method I declare gmap:

return boost::any_cast<T&>(*gmap[key]);

Watching the memory at &boost::any_cast[T&][*gmap[key]] the data goes bad as soon as I pop that stack frame. Which is odd, because according to:

Boost's documentation of any_cast

Returns: If passed a pointer, it returns a similarly qualified pointer to the value content if successful, otherwise null is returned. If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference to (possibly const qualified) ValueType, it returns a reference to the held value.

So, by my understanding, this should not be returning a reference to a local variable.

like image 593
mamidon Avatar asked Oct 11 '22 12:10

mamidon


1 Answers

This is odd, but I figured it out.

Ignoring the fact that it says if T is a reference, it'll return one; I passed it a pointer and got the correct pointer. But for whatever reason, I can't just dereference the return value and return. First I had to store that pointer in an explicit local (as opposed to implicit), dereference that and return.

return *boost::any_cast<T>(&gmap[key]);

Results in incorrect behavior

T* ret = boost::any_cast<T>(&gmap[key]);
return *ret;

Results in the correct behavior.

Don't know why, because AFAIK the local is only explicitly declared in the bottom example. Also, gmap is now a:

map<std::string, boost::any>

Because I don't need to own the any objects now.

like image 200
mamidon Avatar answered Oct 21 '22 02:10

mamidon