Рассмотрим следующий код:
class Widget{};
template<typename T>
T &&foo2(T &&t){
return std::forward<T>( t );
}
/// Return 1st element
template<typename T>
typename std::tuple_element<0, typename std::decay<T>::type >::type &&foo(T &&t){
return std::forward< typename std::tuple_element<0, typename std::decay<T>::type >::type >
( std::get<0>(t) );
}
Widget w;
auto list = std::make_tuple(
w,
Widget()
);
int main()
{
auto &l = foo(list ); // This is NOT work
//auto &l2 = foo2( std::get<0>(list) ); // This one works.
}
http://coliru.stacked-crooked.com/a/4d3b74ca6f043e45
Когда я попытался скомпилировать это, я получил следующую ошибку:
error: invalid initialization of non-const reference of type 'Widget&' from an rvalue of type 'std::tuple_element<0ul, std::tuple<Widget, Widget> >::type {aka Widget}'
Ну, и это будет нормально, но:
-
сначала, что Widget w не является временным. Почему он относится к нему как временный?
-
во-вторых, почему foo2 работает, чем?
P.S. Как вы видите, я пытаюсь написать функцию, которая работает как с lvalue, так и с rvalue. Если первый элемент является временным, я хочу вернуть rvalue, если он не равен lvalue.