2016-03-26 2 views
4

В книге «Эффективный современный C++», в пункте 3 там написано этот кусок кода:C++ станд :: вперед оператора контейнера вызова []

template<typename Container, typename Index> 
decltype(auto) 
authAndAccess(Container&& c, Index i) 
{ 
    authenticateUser(); 
    return std::forward<Container>(c)[i]; 
} 

Я не понимаю, почему вы позвонить std::forward? Если c является ссылкой на rvalue, что он изменит, чтобы вызвать operator[] на rvalue вместо lvalue? Для меня должно быть достаточно c[i].

PS: Я понимаю цель std::forward, когда переменная является параметром функции, как:

template<typename T, typename... Ts> 
std::unique_ptr<T> make_unique(Ts&&... params) 
{ 
    return std::unique_ptr<T>(new T(std::forward<Ts>(params)...)); 
} 

ответ

3

Вполне возможно, что оператор [] для контейнера был перегружен rvalues ​​и lvalues.

auto Container::opeartor[](int i) && -> Container::value_type&; 
auto Container::opeartor[](int i) & -> Container::value_type&; 

Если да, то мы хотим, чтобы убедиться, что если с инициализирован с RValue, мы называем версию RValue оператора [] на с. Это, конечно, нередко для оператора перегрузки [] вести себя по-разному для lvalues ​​и rvalues, но это возможно, поэтому в действительно общем коде нам нужно применить std :: forward к c, прежде чем перенаправлять его на оператор [].

+0

Я думаю, что компилятор знает, что c является rvalue ref, ваш ответ будет применим, если && в параметрах шаблона, или я что-то не хватает? – Incomputable

+0

c становится значением lval после установки переменной. – Thomas

Смежные вопросы