非const引用类型从右值 [英] non-const reference of type from an rvalue

查看:245
本文介绍了非const引用类型从右值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码:

  class Widget {}; 

template< typename T>
T&& foo2(T& t){
return std :: forward< T&
}

///返回第一个元素
template< typename T>
typename std :: tuple_element< 0,typename std :: decay< T> :: type> :: type&& foo(T& t){
return std ::向前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)); //这一个工程。
}

http://coliru.stacked-crooked.com/a/4d3b74ca6f043e45



当我尝试编译我收到以下错误:

 错误:无效的初始化类型'Widget& type'std :: tuple_element< 0ul,std :: tuple< Widget,Widget> > :: type {aka Widget}'

好吧, / p>


  • 首先,



b
$ b

PS正如你所看到的,我尝试写函数,其操作与左值和右值。如果第一个元素是临时的,我想返回rvalue,如果它不是-lvalue。

解决方案

tuple_element 返回元素类型,而不是引用类型(除非元素类型本身是引用类型)。



您需要返回



这可以用条件表达:

  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&&>()))&& 


Consider the following code:

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

When I tried to compile this I got the following error:

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}'

Well, and that would be ok, but:

  • at first, that Widget w is not temporary. Why it treat it like temporary?

  • at second, why foo2 works than?

P.S. As you see, I try to write function which operates both with lvalue and rvalue. If first element is temporary I want to return rvalue, if it is not - lvalue.

解决方案

tuple_element returns the element type, not a reference type (unless the element type is itself a reference type).

You need to have it return a reference type if the type T is a reference type.

This can be expressed with a conditional:

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

Or, more easily, using decltype, since std::get already performs this calculation for you:

decltype(std::get<0>(std::declval<T &&>())) &&

这篇关于非const引用类型从右值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆