Операции перемещения (например, конструктор перемещения) для std::shared_ptrявляются дешевыми , поскольку они в основном являются «крадящими указателями» (от источника к месту назначения; точнее, весь блок управления состоянием «украден» от источника к месту назначения, включая информацию о количестве ссылок) ,
Вместо этого операции копирования при std::shared_ptrвызове увеличивают атомный счетчик ссылок (т.е. не только ++RefCountдля целочисленного RefCountчлена данных, но, например, при вызове InterlockedIncrementв Windows), что дороже, чем просто кража указателей / состояний.
Итак, детально анализируя динамику подсчета ссылок в этом случае:
// shared_ptr<CompilerInvocation> sp;
compilerInstance.setInvocation(sp);
Если вы передаете spпо значению, а затем берете копию внутри CompilerInstance::setInvocationметода, у вас есть:
- При входе в метод
shared_ptrпараметр создается с помощью копии: ref count атомарный инкремент .
- Внутри тела метода, вы скопировать в
shared_ptrпараметр в элементе данных: ЗАДАНИЕ рассчитывать атомное приращение .
- При выходе из метода
shared_ptrпараметр разрушается: ref count атомарный декремент .
У вас есть два атомных приращения и один атомарный декремент, всего три атомарных операции.
Вместо этого, если вы передадите shared_ptrпараметр по значению, а затем std::moveвнутри метода (как это правильно сделано в коде Кланга), вы получите:
- При входе в метод
shared_ptrпараметр создается с помощью копии: ref count атомарный инкремент .
- Внутри тела метода, вы параметр в элемент данных: исх счетчик ничего не изменится! Вы просто крадете указатели / состояния: дорогостоящие операции по подсчету атомных ссылок не требуются.
std::moveshared_ptr
- При выходе из метода
shared_ptrпараметр уничтожается; но поскольку вы перешли на шаге 2, уничтожать нечего, так как shared_ptrпараметр больше ни на что не указывает. Опять же, в этом случае не происходит атомного декремента.
Итог: в этом случае вы получаете только один атомный инкремент подсчета ссылок, т.е. только одну атомарную операцию.
Как вы можете видеть, это намного лучше, чем два атомарных приращения плюс один атомарный декремент (всего три атомарных операции) для случая копирования.