这些天,我目前正在研究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();
}
我已经阅读this post,并且在模板版本中知道这一点。 T &&t
实际上是通用参考。但是在通过调试器检查之后。 t
的类型仍然是Test&&
,我们可以得到Test&& &&t
。通过引用折叠的定义,我们仍然应该得到Test&& t
。
谁能解释为什么会这样?非常感谢!
当您有一个带有名称的变量时,它就是一个左值。这意味着doAThing(X&& t)
接受的参数是右值;但是在函数中是一个称为t的左值。
如果要执行std::move(t).doAThing()
,您将再次通过右值调用结束。