C++0x const RValue 引用作为函数参数

发布于 2024-11-14 15:03:25 字数 799 浏览 3 评论 0原文

我试图理解为什么有人会编写一个采用常量右值引用的函数。

在下面的代码示例中,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;
}

I am trying to understand why someone would write a function that takes a const rvalue reference.

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

楠木可依 2024-11-21 15:03:25

左值强烈倾向于绑定到左值引用,类似地,右值引用强烈倾向于绑定到右值引用。可修改的表达式弱地倾向于绑定到非常量引用。

因此,当编译器进行重载解析时,它会检查是否存在采用右值引用的重载,因为这是强烈首选的。在这种情况下,由于表达式是可修改的右值,因此右值引用重载获胜。

const 右值引用实际上是有用的,它们可用于确保某些内容不会绑定到右值。请记住,右值绑定到 const 左值引用,因此如果您这样做:

template <typename T> void foo(const T& bar) { /* ... */ }

并使用以下方式调用该函数:

foo(createVector());

它会正常工作。然而,有时需要确保只能将左值传递给函数(std::ref 就是这种情况)。您可以通过添加重载来实现此目的:

template <typename T> void foo(const T&&) = delete;

请记住,右值强烈喜欢绑定到右值引用,而可修改表达式更喜欢弱绑定到非常量引用。由于我们有一个 const 右值引用,它基本上意味着每个右值都会绑定到它,因此如果您尝试将右值传递给 foo() ,编译器将给出错误。这是实现此类功能的唯一方法,因此有时很有用。

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.

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.

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) { /* ... */ }

And called the function with:

foo(createVector());

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;

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.

俯瞰星空 2024-11-21 15:03:25

重载解析更喜欢 const 右值而不是 const 左值,因为它是一个右值,并且您将其绑定到右值引用,但在这两种情况下都必须添加 const,因此绝对首选右值引用。

这些东西通常是没有意义的——最好让它们绑定到 const 左值重载。 const 右值没有任何实际用途。

Overload resolution prefers const rvalue over const lvalue because, well, it's an rvalue and you're binding it to an rvalue reference, but you have to add const in both cases, so rvalue reference definitely preferred.

Such things are generally pointless- it's best to leave them binding to the const lvalue overloads. const rvalues don't have any real use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文