为啥这些代码仍然使用左值函数? [复制]

Posted

技术标签:

【中文标题】为啥这些代码仍然使用左值函数? [复制]【英文标题】:Why these code still use the lvalue function? [duplicate]为什么这些代码仍然使用左值函数? [复制] 【发布时间】:2020-01-31 12:54:44 【问题描述】:

这些天我正在研究 C++ 左值和右值。我对下面的代码有点困惑。

class Test 
public:
    Test()
    explicit Test(int _i): i(_i) 

    void doSomething()& 
        cout << "L value ref" << endl;
    

    void doSomething()&& 
        cout << "R value ref" << endl;
    
private:
    int i;
;
void callDoSomething(Test& t) 
    t.doSomething();

void callDoSomething(Test&& t) 
    t.doSomething();


int main() 
    auto a = Test();
    callDoSomething(a);
    callDoSomething(Test());
    return 0;

在上面的代码中,我会得到这样的结果:

L value ref
L value ref

我已经通过调试器检查了上面的代码,并且很确定在这段代码中 sn-p:callDoSomething(Test()); 它将转到右值引用,即callDoSomething(Test&amp;&amp; t)。但是为什么还是调用左值成员函数呢?

我也试过模板,结果还是一样。

template <typename T>
void callDoSomething(T &&t) 
    t.doSomething();

我已经阅读了this post 并且在模板版本中知道这一点。 T &amp;&amp;t 实际上是一个通用参考。但是在通过调试器检查之后。 t 的类型仍然是Test&amp;&amp;,我们可以得到Test&amp;&amp; &amp;&amp;t。通过引用折叠的定义,我们仍然应该得到Test&amp;&amp; t

谁能解释为什么会这样?非常感谢!

【问题讨论】:

@user253751 感谢您的帖子! '它的类型是“对字符串的右值引用”,但它是该类型的左值。”'。这是有道理的。 【参考方案1】:

一旦你有了一个有名字的变量,它就是一个左值。 这意味着doAThing(X&amp;&amp; t) 接受一个右值参数;但在函数中它是一个名为 t 的左值。

如果您要执行std::move(t).doAThing(),您最终会再次收到右值调用。

【讨论】:

以上是关于为啥这些代码仍然使用左值函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要将默认引用参数定义为 const 以便我可以为其分配左值? [复制]

为啥在特殊成员函数中将 r 值绑定到 const 左值引用是非法的?

为啥数组不是左值? [复制]

为啥我在函数内部使用引用并通过引用返回它仍然有效? [复制]

如果存在 VLA,为啥仍然需要 malloc? [复制]

为啥我不能将 const 左值引用绑定到返回 T&& 的函数?