Я настроил тестовый пример, чтобы узнать об идеальной переадресации.
std::string inner(const std::string& str ) {
return "const std::string&";
}
std::string inner(std::string& str ) {
return "std::string&";
}
std::string inner(const std::string&& str ) {
return "const std::string&&";
}
std::string inner(std::string&& str ) {
return "std::string&&";
}
template <typename T> void outer(T&& t) {
std::cout << "t: " << t << std::endl;
std::cout << "perfect forward: " << inner(std::forward<T>(t)) << std::endl;
std::cout << std::endl;
}
void PerfectForwarding()
{
outer("literal");
outer(lvalue);
outer(constlvalue);
outer(rvalue());
outer(constrvalue());
}
std::forward
работает, как и ожидалось. Интересное поведение возникает, когда я реализую свою собственную прямую функцию без идентификатора:
template <typename T> T&& MyForward(T& t)
{
return ((T&&)t);
}
Замена std::forward
на MyForward
во внешнем дает точно такой же результат! Поведение вызывает вопрос, почему используется идентификатор?
Компилятор VS2010
Обновление 1 :Что касается предотвращения вывода типа
AFAIK, правило вывода специального типа активируется только для T&&. Обратите внимание на определение forward, forward(typename identity<T>::type& t)
. Тип аргумента имеет только один &. Фактически, после I изменил MyForward для использования идентификатора и исключил приведение (T&& ), пример не компилируется. На первый взгляд, приведение от lvalue к rvalue, кажется, заставляет работать вперед.
Обновление 2 :проверено на ideone.com с GCC 4.5, то же самое поведение