2

我想知道下面的代码是否会导致每个共享指针的引用计数增加,或者优化器是否会足够聪明地认识到我们实际上并没有复制指针,只是取消引用它。

std::map<int, std::shared_ptr<foo>> map;

...

for (auto kv : map)
    kv.second->func();

kv是一个std::pair<int, std::shared_ptr<foo>>

由于基于范围的 for 循环将返回一个 stack-allocated std::pair,它又存储了 的副本std::shared_ptr我相信此时引用计数会增加。

但是,很明显这个副本只是临时的,这里的目的不是复制所有权,而只是取消引用当前拥有的副本。

但是由于创建该对会导致副作用,即引用计数的增加,这是否意味着优化器将无法优化此副本,或者编译器/优化器编写者识别此用例并能够优化出副本?

4

2 回答 2

6

优化器无权优化它,不管它是否可以。

在您的循环中,有两个相同的副本shared_ptr;一个存储在kv,另一个存储在map. 那时有两个人是无法回避的事实。

如果它对您来说真的很重要,您可以使用auto &kv. 这样,kv是对存储在中的对的引用map

于 2012-07-18T03:56:29.640 回答
1

我认为在这种情况下增加引用计数是一件“好事”。考虑以下假设代码:

for (auto kv : map) {
    releaseAllOtherReferencesToAnyFooThatsNot(kv.second);  // Does what the name says.
    kv.second->tryToCauseACrash();
}

我希望在这种情况下,至少, kv.second 将引用该对象以使其保持活动状态。

于 2012-07-18T03:59:25.500 回答