Я хочу передать объект по ссылке smart-pointer в функцию. Функция может изменить значение объекта по ссылке, но не может изменить саму ссылку. Есть два очевидных способа справиться с этим.
Первый подход заключается в передаче shared_ptr по значению - он является ссылкой, поэтому его самого не нужно передавать по ссылке. Очевидной проблемой при этом является копирование ссылки, что предполагает некоторые накладные расходы на подсчет ссылок.
void foo (shared_ptr<bar> p)
Второй подход заключается в передаче shared_ptr по const-ссылке, что позволяет избежать копирования экземпляра shared_ptr, но вместо этого подразумевает, что для доступа к объекту со ссылкой требуется два уровня разыменования вместо одного.
void foo (const shared_ptr<bar> &p)
На практике эти теоретические накладные расходы обычно оказываются тривиальными и несущественными. Это наводит меня на мысль, что вместо того, чтобы выбирать тот или иной подход для каждого отдельного случая, я должен почти всегда следовать некоторому стандартному соглашению. Что приводит к вопросу...
Существует ли стандартная конвенция о том, какой из этих подходов я должен обычно выбирать? Если да, то что является общепринятым выбором?
EDIT - Возможно, стоит упомянуть - одна из причин рассматривать случай передачи по конст-ссылке заключается в том, что существует уже существующая конвенция, согласно которой большинство экземпляров классов/структур передаются по конст-ссылке, а не по значению, а shared_ptr
- это класс. Конечно, это не тяжелый класс (стоимость копирования невелика), поэтому причины, лежащие в основе этого старого соглашения, могут быть неприменимы.