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

オプティマイザーには、最適化できるかどうかにかかわらず、最適化する権利がありません。

ループ内には、同じの 2 つのコピーがありshared_ptrます。1 つは に保存されkv、もう1 つは に保存されmapます。その時点で2つあるという事実を回避することはできません.

本当に重要な場合は、を使用して、コピーではなく参照を保存できます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 に答える