我试图理解为什么有人会编写一个需要常量右值引用.
在下面的代码示例中,const 右值引用函数(返回“3”)的用途是什么。
为什么重载解析优先考虑 const Rvalue 而不是 const LValue 引用函数(返回“2”)。
#include <string>
#include <vector>
#include <iostream>
std::vector<std::string> createVector() { return std::vector<std::string>(); }
//takes movable rvalue
void func(std::vector<std::string> &&p) { std::cout << "1"; }
//takes const lvalue
void func(const std::vector<std::string> &p) { std::cout << "2"; }
//takes const rvalue???
//what is the point of const rvalue? if const I assume it is not movable?
void func(const std::vector<std::string> &&p) { std::cout << "3"; }
int main()
{
func(createVector());
return 0;
}
左值强烈倾向于绑定到左值引用,类似地,右值引用强烈倾向于绑定到右值引用。可修改的表达式弱地倾向于绑定到非常量引用。
因此,当编译器进行重载解析时,它会检查是否存在采用右值引用的重载,因为这是强烈首选的。在这种情况下,由于表达式是可修改的右值,因此右值引用重载获胜。
const 右值引用实际上是有用途的,它们可以用来确保某些事情does not绑定到右值。请记住,右值绑定到 const 左值引用,因此如果您这样做:
template <typename T> void foo(const T& bar) { /* ... */ }
并使用以下命令调用该函数:
foo(createVector());
效果会很好。然而,有时需要确保只能将左值传递给函数(这种情况就是std::ref
为一)。您可以通过添加重载来实现此目的:
template <typename T> void foo(const T&&) = delete;
请记住,右值强烈喜欢绑定到右值引用,而可修改表达式更喜欢弱绑定到非常量引用。由于我们有一个 const 右值引用,它基本上意味着每个右值都会绑定到它,因此如果您尝试将右值传递给foo()
,你的编译器会报错。这是实现此类功能的唯一方法,因此有时很有用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)