问题描述
我试图理解为什么有人会写一个带有 const rvalue引用的函数。
I am trying to understand why someone would write a function that takes a const rvalue reference.
在下面的代码示例中有什么用途是常量右值参考函数(返回 3)。
为什么重载解析优先于const LValue引用函数上方的const Rvalue(返回 2)。
In the code example below what purpose is the const rvalue reference function (returning "3").And why does overload resolution preference the const Rvalue above the const LValue reference function (returning "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引用。
Lvalues strongly prefer binding to lvalue references, and similarly rvalue references strongly prefer binding to rvalue references. Modifiable expressions weakly prefer binding to a non-const reference.
因此,当您的编译器执行重载解析时,它会检查是否存在需要右值引用的重载,因为强烈首选。在这种情况下,由于expenssion是可修改的右值,所以右值引用重载将获胜。
So when your compiler is doing overload resolution, it checks if there's an overload that takes an rvalue reference, because that's preferred strongly. In this case since the experssion is a modifiable rvalue, so the rvalue reference overload wins.
实际上是用于常量右值引用的,它们可以用来确保某些内容。 不绑定到右值。请记住,右值绑定到const左值引用,因此,如果您这样做:
There is actually use for const rvalue references, they can be used to make sure something does not bind to an rvalue. Remember that an rvalue binds to a const lvalue reference, hence if you did:
template <typename T> void foo(const T& bar) { /* ... */ }
并称为函数
foo(createVector());
效果很好。但是有时希望确保您只能将左值传递给函数(对于 std :: ref
就是这种情况)。您可以通过添加重载来实现此目的:
It'd work fine. However sometimes it is desired to ensure that you can only pass lvalues to a function (this is the case for std::ref
for one). You can achieve this by adding an overload:
template <typename T> void foo(const T&&) = delete;
记住,右值强烈倾向于绑定到右值引用,而可修改表达式则倾向于弱绑定到非const引用。由于我们有一个const rvalue-reference,因此基本上意味着每个单个rvalue都将绑定到该值,因此,如果尝试将rvalue传递给 foo()
,则编译器将给出一个错误。这是实现这种功能的唯一方法,因此有时很有用。
Remember, rvalues strongly prefer binding to rvalue references, and modifiable expressions prefer weakly binding to non-const references. Since we have a const rvalue-reference, it basically means that every single rvalue will bind to this, hence if you try to pass a rvalue to foo()
, your compiler will give an error. This is the only way to achieve such functionality, and thus is sometimes useful.
这篇关于C ++ 0x const RValue引用作为函数参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!