看下面例子:
test(0)调用的是函数是:
template<typename T>
void test(T&& t) {std::cout << "右值引用" << std::endl;
}
test(n)调用的是函数是:
template<typename T>
void test(T& t) {std::cout << "左值引用" << std::endl;
}
也就是说 0 是右值, n 是左值,现在假设我要把 n变为右值引用 ,让它调用test(T&& t)函数怎么做?
方案1:
方案2:
以下方法是错误的:
为什么?
这是因为 r1
, r2
, 和 r3
本身都是左值,尽管它们被声明为右值引用(int&&
)。
原因分析:
-
右值引用变量是左值:
虽然r1
,r2
,r3
的类型是int&&
(右值引用),但它们本身是具名的变量,因此是左值。在 C++ 中,所有的具名变量都是左值,即使它们的类型是右值引用。 -
函数重载解析规则:
-
test(T& t)
接受一个左值引用,可以绑定到左值(如r1
,r2
,r3
)。 -
test(T&& t)
是一个转发引用(universal reference),但它只能绑定到右值(如临时对象或std::move(x)
的结果)。由于r1
,r2
,r3
是左值,所以不会匹配这个版本。
-
法则1:在 C++ 中,所有的具名变量都是左值,即使它们的类型是右值引用。