Действительно ли полезно использовать ссылки на rvalue?

Типичная причина введения ссылок на Rvalue в C ++ заключается в устранить (оптимизировать) лишнее копирование во время оценки сложных выражений C ++.

Тем не менее, есть два методы оптимизации компилятора для C ++ 98 / C ++ 03, которые в основном служат той же цели, а именно

Существует ли какой-либо реальный случай использования, когда вышеуказанные методы (с соответствующим образом написанным кодом) не могут устранить лишнее копирование, но ссылки на значения могут быть успешными?

0

Решение

Ссылки на rvalue разработаны с двумя целями:

  • переместить семантику
  • идеальная пересылка

Переместить семантику

В общем, одна из целей семантики перемещения — это оптимизация копирования. Там, где вы можете копировать, вы можете просто перемещать ресурсы, удерживаемые объектом.

std::string str("The quick brown fox jumps over the lazy dog.");
std::cout << str;      // Do something
func(std::move(str));  // You do not need str in the subsequent lines, and so move

Кроме того, компилятор может оптимизировать возвращаемое значение функции, где RVO может не применяться

std::vector<std::string> read_lines_from_file(const std::string& filename);

auto lines = read_lines_from_file("file1.txt");  // Can possibly be optimized with RVO
// Do something with lines
lines = read_lines_from_file("file2.txt");  // RVO isn't applicable, but move is
// Do something with lines

Если вы реализуете семантику перемещения в своих классах, скорее всего, вы будете испытывать значительное повышение производительности, когда будете помещать их в контейнеры. Рассматривать std::vector, Всякий раз, когда вы изменяете элементы std::vectorЧерез некоторое время произойдет некоторое перераспределение и смещение элементов. В C ++ 98 элементы в основном копируются[1], что является ненужным, так как логически существует только одно представление объекта, которое необходимо в один момент времени. С семантикой перемещения, контейнеры типа std::vector можно просто перемещать объекты, устраняя лишние копии и, следовательно, повышать производительность вашей программы.

Одним из очень важных применений семантики перемещения является не только оптимизация, но и реализация уникальной семантики владения. Один очень хороший пример std::unique_ptr в котором его можно перемещать только (его нельзя копировать), поэтому вам гарантировано (при правильном использовании), что есть только один std::unique_ptr который управляет указателем или ресурсом.


Идеальная пересылка

Идеальная пересылка использует rvalue-ссылки и специальные правила вывода шаблонов, чтобы мы могли реализовать идеальные функции пересылки, то есть функции, которые могут пересылать аргументы правильно и без создания копий.

Примеры std::make_shared и предстоящий std::make_unique, Также новые emplace* методы контейнеров, тот, который вы найдете очень полезным и удобным (не говоря уже о том, что он также будет очень эффективным).


Этот ответ обеспечивает очень хорошее и полное объяснение ссылок на rvalue в отношении семантики перемещения и идеальной пересылки.


[1] Одна вещь, которую я услышал из одного из выступлений Бьярна Страуструпа[источник нужен] в том, что контейнеры обычно реализуют некоторую специальную семантику перемещения. Поэтому, как он сказал, вы можете не испытывать такого ускорения.

4

Другие решения

Если вам нужен один единственный аргумент, почему ссылки на rvalue важны, это unique_ptr, Это архетип ресурсов управления классами SBRM. Ресурсы по определению не копируются, но менеджеры должны движимое

Собственный контейнер разнородных связанных объектов прост для реализации в качестве контейнера unique_ptrс базового класса, и это очень распространенная идиома программирования. До ссылок на rvalue никогда не было вполне возможно реализовать это чисто на «родном C ++», и всегда требовалось ручное обслуживание.

Потоки и блокировки являются дополнительными примерами ресурсов.

Короче говоря, оптимизация — это только одна часть истории, но подвижность — это само по себе качество, с которым просто было нелегко справиться, прежде чем ссылаться на rvalue.

15

Есть две причины для использования ссылок на rvalue и перемещения
семантика.

  • Для большинства программистов самый важный (или даже единственный
    причина, которая влияет на их код) является возможность
    поддержка «ограниченная копия». (Извините, я не знаю хорошего имени
    для этого.) Как классы iostream, например: вы не
    хотите поддержать копирование как таковое, но вы хотите разрешить
    строительство в отдельной функции. Типичным примером может быть
    поток журнала: вы хотите вернуть соответствующий поток журнала из
    функция, но вы хотите только один экземпляр, чей
    деструктор будет гарантировать, что действия регистрации (то есть отправка
    электронная почта, размещение в системном журнале и т. д.) являются атомарными.

  • Иногда его также можно использовать для оптимизации; Вы упоминаете
    такие вещи, как оптимизация возвращаемого значения и копирование, но они
    не всегда применяется, особенно с заданием. Как правило, в
    В таких случаях вы игнорируете ссылки и перемещаетесь до
    профилировщик сказал, что есть проблема, но если вы
    реализуя библиотеку, у вас может не быть такой роскоши.

1
По вопросам рекламы [email protected]