我想知道以下代码是否会导致每个共享指针的增加引用计数,或者优化程序是否足够聪明以识别我们实际上不是< strong>复制指针,只需解除引用。
std::map<int, std::shared_ptr<foo>> map;
...
for (auto kv : map)
kv.second->func();
kv
是std::pair<int, std::shared_ptr<foo>>
由于基于范围的for循环将返回堆栈分配的std::pair
,而后者又存储std::shared_ptr
的副本,我相信引用计数会在这一点上增加。
但是,很明显这个副本只是暂时的,这里的目的不是复制所有权,而只是取消引用当前拥有的副本。
但是由于该对的创建导致aa 副作用,引用计数增加,这是否意味着优化器将无法优化此副本,或者具有编译器/优化器编写者认识到这个用例并且能够优化副本吗?
答案 0 :(得分:6)
优化器没有正确的来优化它,无论它是否可以。
在你的循环中,有两个相同shared_ptr
的副本;一个存储在kv
中,另一个存储在map
中。在这一点上,有两个事实无法解决。
如果确实对您很重要,您可以使用auto &kv
存储参考而不是副本。这样,kv
就是对map
中存储的货币对的引用。
答案 1 :(得分:1)
在这种情况下,我认为增加引用计数是一件“好事”。请考虑以下假设代码:
for (auto kv : map) {
releaseAllOtherReferencesToAnyFooThatsNot(kv.second); // Does what the name says.
kv.second->tryToCauseACrash();
}
我希望在这种情况下,至少kv.second会引用一个对象来保持它的存活。