Подтвердить что ты не робот

Зачем использовать std:: forward на контейнере перед доступом к элементу?

Скотт Мейерс в своей новой книге "Эффективный современный С++" показывает следующую функцию в качестве примера использования decltype(auto) (стр. 28):
template<typename Container, typename Index>
decltype(auto) 
authAndAccess(Container&& c, Index i)
{
  authenticateUser();
  return std::forward<Container>(c)[i];
}

Мой вопрос прост. Зачем нам std::forward применять к c здесь? Мы не проходим c в любом месте, мы вызываем на нем operator[]. И ни один из стандартных контейнеров не имеет отказоустойчивых перегрузок (перегрузки r-value/l-value) operator[].

Поэтому я вижу только две причины для этого std::forward:

  • Для учета потенциальных контейнеров, которые реализуют рефлексивные перегрузки operator[].
  • Для согласованности: всякий раз, когда используется переменная, объявленная как перенаправление (универсальная) ссылка, примените к ней std::forward. Период.

Любые другие причины?

4b9b3361

Ответ 1

Причина № 1 является соответствующей. Когда вы реализуете универсальную функцию, вы не идете "Что делают эти конкретные типы, о которых я знаю?", А "Что я знаю о родовой вещи, с которой я работаю?".

Общий контейнер ничего не говорит о ссылочной квалификации, поэтому вы переходите.

Конечно, причина № 2 гораздо легче запомнить и обосновать, поэтому вы должны следовать этому.

Я не думаю, что есть другие причины.