为什么这些代码仍然使用 lvalue 函数?

Why these code still use the lvalue function?

本文关键字:lvalue 函数 代码 为什么      更新时间:2023-10-16

这些天我目前正在学习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

我已经通过调试器检查了上面的代码,并且非常确定在此代码片段中:callDoSomething(Test());它将转到callDoSomething(Test&& t)的右值引用。但是为什么它仍然调用左值成员函数呢?

我也尝试了模板,但仍然得到相同的结果。

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

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

谁能解释为什么会这样?多谢!

当你有一个带有名称的变量时,它是一个左值。 这意味着doAThing(X&& t)接受一个右值的参数;但在函数中,它是一个称为 T 的左值。

如果你要做std::move(t).doAThing()你最终会再次得到一个右值调用。