考虑以下代码:
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}'
好吧,那没关系,但是:
首先,小部件w不是临时的。为什么把它当作临时的呢?
第二,为什么foo2比呢?
PS如您所见,我尝试编写可同时使用左值和右值的函数。如果第一个元素是临时元素,我想返回右值,如果不是-左值。
tuple_element
返回元素类型,而不是引用类型(除非元素类型本身是引用类型)。
如果类型T
是引用类型,则需要让它返回引用类型。
这可以用条件表示:
typename std::conditional<std::is_lvalue_reference<T>::value,
typename std::add_lvalue_reference<
typename std::tuple_element<0, typename std::decay<T>::type >::type>::type,
typename std::tuple_element<0, typename std::decay<T>::type >::type>::type
或者,更容易使用decltype
,因为std::get
已经为您执行了此计算:
decltype(std::get<0>(std::declval<T &&>())) &&
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句