Как узнать, будет ли перемещен объект, переданный как r-значение?

Я передаю лямбда-функцию в функцию, которая принимает ее как ссылку на r-значение.

Если моя лямбда определена в самом вызове функции, мне все равно, что будет с ней позже.
Но если моя лямбда-переменная (скажем, я хочу использовать ее несколько раз), я хочу знать, что она не перемещена.

Есть ли способ узнать, будет ли он перемещен из или нет, что сделает его непригодным для использования или пригодным для использования после возвращения вызова?

РЕДАКТИРОВАТЬ:

Просто чтобы уточнить, лямбда ничего не захватывает. Что меня волнует, так это сам функтор: auto fn = [](int a){ return a; };

Позвольте мне сделать это еще сложнее. Я передам функтор как rvalue: std::move(fn)

std:: move - только приведение. Он ничего не перемещает, но аргумент rvalue в вызываемом объекте теперь привязывается к правильному rvalue.

Вопрос в том, fn гарантированно переехать? Это гарантированно не будет перемещено? Есть ли вообще гарантия? Могу ли я заставить его вести себя так или иначе, или это до вызываемого?

Я хочу знать, потому что я хочу знать, могу ли я пройти fn в качестве параметра функции дважды.

РЕДАКТИРОВАТЬ № 2:

Давайте возьмем другой случай. Я должен вызвать функцию с контейнером. Вектор, карта или что-то еще. Сигнатура функции говорит &&, Я могу обернуть свой контейнер с помощью STD Move или STD вперед, чтобы получить rvalue ref в вызываемый объект. Это на самом деле одно и то же, так как они просто прославленные актеры.

Теперь, допустим, я использовал std forward, потому что мне действительно нравится, когда мой контейнер никуда не уходит.

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

1 ответ

Решение

Хорошо, если функция принимает универсальную ссылку, и вы хотите запретить перемещение, есть много вариантов для выбора, среди прочего:

  1. Передача по постоянной ссылке (C++17 имеет std::as_const() чтобы упростить это).
  2. Сохраните его как локальный и не конвертируйте в rvalue-reference. Кажется, ты это делаешь.
  3. Используйте что-то для явного преобразования rvalue-ссылки в lvalue-ссылку.

Конечно, если лямбда не захватывает локальные значения по значению, которые имеют другую семантику перемещения, чем семантика копирования, и вызываемая функция на самом деле не использует это преимущество, дело в споре.

Будет ли это на самом деле воспользоваться возможностью?
Изучите договор, а затем просто доверьтесь ему или попробуйте проверить выполнение. Там нет ярлыка.

Не будем даже упоминать, что C++ позволяет программисту явно отказаться от (ограниченной) безопасности, которую он обеспечивает.

Другие вопросы по тегам