Rvalue references and std::forward


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

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

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

  1. int和amp&i=42;且int i=42

是的。前一个变量是对绑定到临时int对象的int的右值引用。Latter变量是一个int对象。前者是指代对象的一种不必要的复杂方式。

不,在2的上下文中没有区别。你问题的一部分。

  1. 。。。"如果arg是左值引用,则函数返回arg而不修改其类型。"

这句话本身并不完全准确。假设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

我想说这个函数在这里解释得很好。当在一个可以具有通用引用的上下文中(T&&其中T是为该上下文推导的),forward确保您传递具有相同l/r值特征的参数。

最新更新