Rvalue引用和std :: forward

时间:2016-07-22 10:42:02

标签: c++ c++11

  1. int&& i = 42;int i = 42;之间有什么区别吗?

  2. 关于std::forward,我在网上读到“如果arg是左值引用,该函数返回arg而不修改其类型。”但是以下代码:

  3.  
    void f(int& k)
    {
        std::cout << "f(int&) " << k << std::endl;
    }
    
    void f(int&& k)
    {
        std::cout << "f(int&&) " << k << std::endl;
    }
    
    int main(void)
    {
        int i = 42;
        int& j = i;
        int&& k = 42;
    
        f(i);
        f(j);
        f(k);
    
        f(std::forward<int>(i));
        f(std::forward<int>(j));
        f(std::forward<int>(k));
        return 0;
    }
    

    打印出来

    f(int&) 42
    f(int&) 42
    f(int&) 42
    f(int&&) 42
    f(int&&) 42
    f(int&&) 42
    

    我想知道为什么第4和第5行不是f(int&) 42,根据我上面提到的引用。

2 个答案:

答案 0 :(得分:1)

  
      
  1. int&amp;&amp;和我= 42;和int i = 42; ?
  2.   

是。前变量是int的右值引用,它绑定到临时int对象。后置变量是int对象。前者是引用对象的一种不必要的复杂方式。

不,你问题的部分内容没有区别。

  
      
  1. ...&#34;如果arg是左值引用,则该函数返回arg而不修改其类型。&#34; ...
  2.   

报价本身并不完全准确。它假设forward的模板参数是从arg的类型推导出来的。您没有使用推导类型,而是int,而不是从左值参考推断出来的。

  

我想知道为什么第4和第5行不是f(int&) 42

int不是左值参考,因此报价不适用于第4行。

让我们考虑一下std::forward做什么?它这样做:

Returns: static_cast<T&&>(t).

现在,如果Tint,那么它会static_cast<int&&>(t),因此无论t的类型如何,结果类型都是右值引用。如果使用非左值引用作为std::forward的类型参数,则其行为与std::move完全相同。

为了遵守报价的假设,你可以做到:

f(std::forward<decltype(i)>(i));
f(std::forward<decltype(j)>(j));
f(std::forward<decltype(k)>(k));

这样,输出为:

f(int&&) 42
f(int&) 42
f(int&&) 42

答案 1 :(得分:0)

我会说这个功能很好地解释了here。在可以具有通用引用的上下文中(T&amp;&amp;其中T是针对该上下文推导出的),forward确保您使用相同的l / r-valueness特性来中继参数。