C++ 左值引用和右值引用之间的转换
int retVal(int &&v)
{
cout << "右值引用:";
return v;
}
int retVal(int &v)
{
cout << "左值引用:";
return v;
}
int retVal(const int &v)
{
cout << "const 左值引用:";
return v;
}
int getVal()
{
return 999;
}
// 主函数
int main()
{
int a = 100;
int &b = a;
cout << retVal(static_cast<int &&>(a)) << endl;
cout << retVal(static_cast<int &&>(b)) << endl;
cout << retVal(110) << endl;
system("pause");
return EXIT_SUCCESS;
}
输出:
右值引用:100
右值引用:100
右值引用:110
请按任意键继续. . .
可见,上面三个输出,都是精准匹配到的是int retVal(int &&v)
函数。另外左值或左值引用可以通过static_cast<int &&>()
强转成右值类型(这个是 std::move 的基础?);反过来右值不能通过static_cast<int &>()
转成左值引用。如,cout << retVal(static_cast<int&>(getVal())) << endl;
这样子会报错。
下面我们注释掉右值函数:
//int retVal(int &&v)
//{
// cout << "右值引用:";
// return v;
//}
int retVal(int &v)
{
cout << "左值引用:";
return v;
}
int retVal(const int &v)
{
cout << "const 左值引用:";
return v;
}
int getVal()
{
return 999;
}
NS_END
int main()
{
int a = 100;
int &b = a;
cout << retVal(static_cast<int &&>(a)) << endl;
cout << retVal(static_cast<int &&>(b)) << endl;
cout << retVal(110) << endl;
system("pause");
return EXIT_SUCCESS;
}
输出:
const 左值引用:100
const 左值引用:100
const 左值引用:110
请按任意键继续. . .
可见,编译器匹配到的是int retVal(const int &v)
函数。也就是说,int &&
可以转换成const int &v
类型。经测试,不能转换成int &v
类型。
Note: 区分移动和拷贝的重载函数通常有一个版本接受一个
const T&
,而另一个版本接受一个T&&
。 ——《C++ Primer》 P482
所以,一般会重载两个函数,一个是右值引用参数,另一个是 const 左值引用参数。
另外, 函数尾后引用重载版本声明样式如下:
class Foo {
public:
Foo sorted() &&; // 可用于可改变的右值
Foo sorted()const &; // 可用于任何类型的Foo
private:
vector<int> data;
——《C++ Primer》 P484
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了