Переместите значение изshared_ptr или скопируйте, если оно является общим.C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Переместите значение изshared_ptr или скопируйте, если оно является общим.

Сообщение Anonymous »

Контекст
Мы храним данные треугольной сетки в больших буферах как Buffer = std::vector. Размер этих буферов может легко достигать 1 ГБ.
Мы также разделяем эти буферы как SharedBuffer = std::shared_ptr. Такие общие буферы, конечно, помечены как const, потому что мы не хотим, чтобы они были случайно изменены.
Алгоритмы обработки сетки обычно изменяют данные сетки, поэтому они могут работать только с Buffer внутри. Если у кого-то есть SharedBuffer и он хочет вызвать такой алгоритм, ему придется полностью скопировать буфер независимо от того, является ли SharedBuffer общим для кого-либо. Это ненужное копирование, которого я хотел бы избежать.
Вопрос
Поэтому я хотел бы иметь следующую функцию:

Код: Выделить всё

T stealOrCopyValue(std::shared_ptr pValue);
  • Вызывающий гарантирует, что pValue != NULL.
  • Если pValue является единственной сильной ссылкой, то возвращается значение, созданное с помощью move.
  • Если pValue имеет какие-либо другие ссылки, то значение, созданное копированием, возвращается. возвращается.
Как это можно реализовать на C++?
Примечания
Имея такую функцию, я могу преобразовать SharedBuffer в Buffer следующим образом:

Код: Выделить всё

Buffer unwrapBuffer(SharedBuffer&& pBuffer) {
std::shared_ptr pMutBuffer = std::const_pointer_cast(std::move(pBuffer));
return stealOrCopyValue(std::move(pMutBuffer));
}
Поэтому, если я перемещаю SharedBuffer в этот конвертер, фактические байты данных внутри Buffer не копируются, если это единственная ссылка на него.
Я думаю, это называется поведением «клонирования при записи», и оно существует в Rust как Arc::make_mut, хотя оно немного отличается, поскольку возвращает исходное значение, а не удаляет его.

Подробнее здесь: https://stackoverflow.com/questions/797 ... -is-shared
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»