Reputation: 28659
I would like to know whether the following code will result in an increase in the reference count for each shared pointer, or whether the optimizer will be clever enough to recognize that we are not in fact copying the pointer, just dereferencing it.
std::map<int, std::shared_ptr<foo>> map;
...
for (auto kv : map)
kv.second->func();
kv
is a std::pair<int, std::shared_ptr<foo>>
Since the range-based for-loop will return a stack-allocated std::pair
, which in turn stores a copy of the std::shared_ptr
, I believe that the reference count will be increased at this point.
However, it is plain to see that this copy is just temporary, and the intention here is not to copy ownership, but just dereference the currently owned copy.
But since the creation of the pair causes a a side-effect, an increase in the reference count, does this mean the optimizer will not be able to optimize this copy out, or have the compiler/optimizer writers recognized this use-case and been able to optimize out the copy?
Upvotes: 2
Views: 2445
Reputation: 4490
I would think it is a "good thing" to increment the reference count in this case. Consider the following hypothetical code:
for (auto kv : map) {
releaseAllOtherReferencesToAnyFooThatsNot(kv.second); // Does what the name says.
kv.second->tryToCauseACrash();
}
I would hope in this case, at least, kv.second would have a reference to the object to keep it alive.
Upvotes: 1
Reputation: 473312
The optimizer doesn't have the right to optimize it out, whether it could or not.
Within your loop, there are two copies of the same shared_ptr
; one stored in kv
and the other stored in map
. There's no getting around the fact that there are two of them at that point.
If it really matters that much to you, you can store a reference rather than a copy, using auto &kv
. That way, kv
is a reference to the pair stored in map
.
Upvotes: 6