Почему идеальная функция пересылки должна быть шаблонной?

Почему следующий код валиден:

template<typename T1>
void foo(T1 &&arg) { bar(std::forward<T1>(arg)); }

std::string str = "Hello World";
foo(str); // Valid even though str is an lvalue
foo(std::string("Hello World")); // Valid because literal is rvalue

Но не валиден:

void foo(std::string &&arg) { bar(std::forward<std::string>(arg)); }

std::string str = "Hello World";
foo(str); // Invalid, str is not convertible to an rvalue
foo(std::string("Hello World")); // Valid

Почему значение l в примере 2 не разрешается так же, как в примере 1?

Также, почему стандарт считает важным указывать тип аргумента в std::forward, а не просто выводить его? Простой вызов forward показывает намерение, независимо от типа.

Если это не стандартная вещь, а просто мой компилятор, то я использую msvc10, что объясняет плохую поддержку C++11.

Спасибо

Правка 1: Изменил литерал "Hello World" на std::string("Hello World"), чтобы сделать r-значение.

18
задан Mranz 1 December 2011 в 23:24
поделиться