Мы храним данные треугольной сетки в больших буферах как Buffer = std::vector. Размер этих буферов может легко достигать 1 ГБ.
Мы также разделяем эти буферы как SharedBuffer = std::shared_ptr. Такие общие буферы, конечно, помечены как const, потому что мы не хотим, чтобы они были случайно изменены.
Алгоритмы обработки сетки обычно изменяют данные сетки, поэтому они могут работать только с Buffer внутри. Если у кого-то есть SharedBuffer и он хочет вызвать такой алгоритм, ему придется полностью скопировать буфер независимо от того, действительно ли SharedBuffer является общим для кого-либо. Это ненужное копирование, которого я хотел бы избежать.
Вопрос
Поэтому я хотел бы иметь следующую функцию:
Код: Выделить всё
T stealOrCopyValue(std::shared_ptr pValue);- Вызывающая программа гарантирует, что pValue != NULL.
- Если pValue является единственной сильной ссылкой, то возвращается значение, созданное с помощью move.
- Если pValue имеет какие-либо другие ссылки, то значение, созданное копированием, возвращается. возвращается.
Примечания
Имея такую функцию, я могу преобразовать SharedBuffer в Buffer следующим образом:
Код: Выделить всё
Buffer unwrapBuffer(SharedBuffer&& pBuffer) {
std::shared_ptr pMutBuffer = std::const_pointer_cast(std::move(pBuffer));
return stealOrCopyValue(std::move(pMutBuffer));
}
Я думаю, это называется поведением «клонирования при записи», и оно существует в Rust как Arc::make_mut, хотя оно немного отличается, поскольку возвращает исходное значение, а не перемещает его. прочь.
Подробнее здесь: https://stackoverflow.com/questions/797 ... -is-shared
Мобильная версия