【问题标题】:How reference deduce works?参考推论如何工作?
【发布时间】:2017-12-25 12:13:48
【问题描述】:

可以复制到this

我读过Effective Modern C++。在Item 1下找到了一个案例供大家参考:

最后一个例子f(27);我在VS2013下做了一个测试。

void process(int& x)
{
    std::cout << "int&" << std::endl;
}
void process(int&& x)
{
    std::cout << "int&&" << std::endl;
}
template<typename T>
void f(T&& param)
{
    std::cout << "------------------------------------------------" << std::endl;
    if (std::is_lvalue_reference<T>::value)
    {
        std::cout << "T is lvalue reference" << std::endl;
    }
    else if (std::is_rvalue_reference<T>::value)
    {
        std::cout << "T is rvalue reference" << std::endl;
    }
    else
    {
        std::cout << "T is NOT lvalue reference" << std::endl;
    }
    std::cout << "param is: " << typeid(param).name() << std::endl;

    process(std::forward<T>(param));
    process(param);
}
int getINT()
{
    int x = 10;
    return x;
}
int _tmain(int argc, _TCHAR* argv[])
{   
    f(10);
    f(getINT());

    return 0;

}

这是输出:

------------------------------------------------
T is NOT lvalue reference
param is: int
int&&
int&
------------------------------------------------
T is NOT lvalue reference
param is: int
int&&
int&

我发现在模板函数中,没有std::forward&lt;T&gt;(param),会调用process(int&amp; x),但是根据书,param的类型应该是右值引用,所以应该调用process(int&amp;&amp; x)。但这种情况并非如此。 是不是我误会了什么?

这是我从其他thread 找到的转发参考:

【问题讨论】:

  • 您的问题有很多,但我很确定它是“为什么将右值引用视为左值?”
  • 谢谢,我会结束我的问题
  • “右值引用”是指它绑定到右值,而不是它的名字是右值

标签: c++ c++11 rvalue-reference effective-c++ forward-reference


【解决方案1】:

您将类型与 value categories 混淆了。作为命名参数,param 是一个左值,那么对于process(param); 会调用process(int&amp; x)

这就是为什么我们应该使用std::forwardforwarding reference;在这种情况下,std::forward&lt;T&gt;(param)param 转换为右值,然后将调用process(int&amp;&amp; x)(如预期的那样)。

【讨论】:

  • 所以你的意思是如果我有int&amp;&amp; x = 10;,那么x是什么类型?不是右值引用?
  • @sflee 它的类型是int&amp;&amp;,但它是一个左值。左值不能绑定右值引用,那么process(int&amp;&amp; x)在被调用时不会被选中。
  • 表达式 x 的类型为 int 。表达式永远没有引用类型。如果谈论实体x,我倾向于说“x 的声明类型是int&amp;&amp;”;如果你不做这个区分,那么谈论“x的类型”是模棱两可的
  • @M.M 我明白你的意思。在这里,我认为“x 的声明类型是int&amp;&amp;,但它的值类别是左值”对 OP 来说应该是最清楚的。
  • @songyuanyao 实体x 没有值类别 - 只有表达式才有值类别。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多