Объявление std::forward

221
07 октября 2021, 11:30

Почему std::forward объявлён так?

  template <class _Ty>
_NODISCARD constexpr _Ty&& forward(
    remove_reference_t<_Ty>& _Arg) noexcept;

Если с точки зрения пользовательского интерфейса лучше было написать так

   template <class _Ty>
_NODISCARD constexpr auto forward(
     _Ty&& _Arg) noexcept -> decltype(_Arg);
Answer 1

std::forward две перегрузки - основная и вспомогательная. Из вашего вопроса не ясно, является ли предложенный вами вариант заменой для основной перегрузки или для них обеих сразу. Но в любом случае: )

Не понимаю вашего предложения в принципе. Основная функциональность std::forward (первая перегрузка из двух) заключается в непосредственном форвардинге аргументов. Аргументы - это именованные переменные. И как все именованные переменные, они являются lvalue. Именно поэтому первая перегрузка std::forward принимает именно lvalue-ссылку в качестве аргумента. Задача std::forward - в зависимости от типа _Ty либо выполнить конвертацию lvalue в xvalue (как это делает std::move), либо оставить lvalue как lvalue.

Например, в контексте функции

template <typename T> void foo(T &&t)
{
  std::forward<T>(t);
}

вызванной с rvalue аргументом

foo(42);

тип T будет дедуцирован как int. При этом выражение t внутри foo является lvalue.

В результате такой дедукции предложенная вами версия std::forward получит _Ty == int и будет иметь параметр типа int &&. Но, как сказано выше, внутри foo выражение t является lvalue. Его невозможно будет передать в ваше std::forward, ибо последнее будет требовать rvalue в качестве аргумента. То есть c вашей версией std::forward этот пример даже не будет компилироваться.

Отдельно можно заметить, что в объявлении параметра

remove_reference_t<_Ty>& _Arg

тип _Ty находится в недедуцируемом контексте (non-deduced context), что заставляет пользователя при вызове std::forward всегда явно руками указывать шаблонный аргумент. Это критически важно для правильной функциональности std::forward.

В вашем же варианте фактически получилась универсальная ссылка, т.е. шаблонный аргумент вдруг является дедуцируемым. Автоматически дедуцируемого форвардинга в C++ пока что реализовать невозможно.

READ ALSO
Почему и как это работает?(Heap and Stack)

Почему и как это работает?(Heap and Stack)

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

65
Загрузка из std::map в шаблон

Загрузка из std::map в шаблон

Сделал частитчно менеджер загрузки спрайтов и моделей 3dЗагружается через load_manager

157
webcomponent почему элемент выпал из потока?

webcomponent почему элемент выпал из потока?

Задача: организовать максимально простое программное добавление/удаление строк в таблицу

141
Не вызывается async функция

Не вызывается async функция

JS(React native) только изучаю после JAVA, не пойму понять в чем фишка и почему не вызывается функция async внутри функции? Где моя ошибка?

83