Почему const shared_ptr <const T> и const shared_ptr <T> и показывают разные подсчеты ссылок?

Для следующего фрагмента кода он показывает разные значения ссылок в методах. Может ли кто-нибудь объяснить, почему эти значения различны?

class Foo {
};

void f1( const std::shared_ptr<Foo>& ptr ) {
   std::cout << "f1(): counts: " << ptr.use_count() << std::endl;
}

void f2( const std::shared_ptr<const Foo>& ptr ) {
   std::cout << "f2(): counts: " << ptr.use_count() << std::endl;
}

int main() {
   std::shared_ptr<Foo> ptr( new Foo );
   std::cout << "main(): counts: " << ptr.use_count() << std::endl;

   f1( ptr );
   f2( ptr );

   std::cout << "main(): counts: " << ptr.use_count() << std::endl;

   return 0;
}

Соответствующий вывод:

main(): counts: 1
f1(): counts: 1
f2(): counts: 2
main(): counts: 1

Ответ 1

Обратите внимание, что std::shared_ptr<Foo> и std::shared_ptr<const Foo> являются разными типами (т.е. экземпляры шаблона класса с разными аргументами типа шаблона являются разными типами).

Когда вы передаете ptr (т.е. a std::shared_ptr<Foo>) на f2, он не может напрямую ссылаться на std::shared_ptr<const Foo>; временный std::shared_ptr<const Foo> должен быть построен, а затем привязан к параметру ptr. Построенная собственность shared_ptr владеет оригинальным shared_ptr, поэтому use_count увеличивается до 2 в f2().

Временное уничтожается, когда f2( ptr ); заканчивается; то use_count уменьшается до 1.