Зачем использовать 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
. Период.
Любые другие причины?
Ответы
Ответ 1
Причина № 1 является соответствующей. Когда вы реализуете универсальную функцию, вы не идете "Что делают эти конкретные типы, о которых я знаю?", А "Что я знаю о родовой вещи, с которой я работаю?".
Общий контейнер ничего не говорит о ссылочной квалификации, поэтому вы переходите.
Конечно, причина № 2 гораздо легче запомнить и обосновать, поэтому вы должны следовать этому.
Я не думаю, что есть другие причины.