Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a std::map rebalance during the invocation of a const function?

Tags:

c++

I have a const std::map<std::string, std::vector<double>> member variable and a function const std::vector* foo(). I'd like this function to sometimes return a pointer to an element of this map. But I'm concerned that the map might rebalance - even during a std::map function marked const - so invalidating my returned pointer. I know that any subsequent modification of the map will invalidate my pointers but that cannot happen as I've marked the member variable const.

I can't return a reference as on occasions, foo needs to return nullptr.

Is what I'm doing safe?

like image 995
Franzl Avatar asked Nov 11 '14 14:11

Franzl


3 Answers

The standard is quite clear: the only thing that can invalidate an iterator or a pointer or reference into a map is removing the element it points to. You can even insert other elements without invalidating your pointer. See §23.2.4/9:

The insert and emplace members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements.

like image 54
James Kanze Avatar answered Oct 06 '22 01:10

James Kanze


Fortunately the C++11 standard makes this clear:

§23.2.2/1:

For purposes of avoiding data races (17.6.5.9), implementations shall consider the following functions to be const: begin, end, rbegin, rend, front, back, data, find, lower_bound, upper_bound, equal_range, at and, except in associative or unordered associative containers, operator[].

So you are safe. The map cannot rebalance when calling a const function.

like image 23
Bathsheba Avatar answered Oct 06 '22 00:10

Bathsheba


I assume you mean "const std::vector* foo()."

Rebalancing is not relevant here. The answer is that your returned pointer is not invalidated as long as the item to which it points remains in the std::map (and the map is not destroyed or moved).

Note that std::map (which you shouldn't be using anyway - See Chandler's talk at CppCon 2014: http://youtu.be/fHNmRkzxHWs) will never move items once they are added to the container, even when rebalancing. The address of an item in a map will be the same as long as that item is in the container. This is true without regard to rebalancing or additions and/or removal of other items.

like image 42
Jon Kalb Avatar answered Oct 06 '22 00:10

Jon Kalb