c++ - 为什么 C++ 在函数调用时优先考虑右值引用而不是 const 引用?

标签 c++ pass-by-reference rvalue-reference pass-by-const-reference pass-by-rvalue-reference

<分区>

所以我用C++ 11写了一段代码

#include <iostream>
using namespace std;

void print (int &&a)
{
    cout<<"rval ref";
}

void print (const int& a)
{
    cout<<"const ref";
}

int main()
{
    print(9);   
}

代码的输出令人着迷,它是“rval reference” 但是如果我重写代码只是删除一个函数定义:

#include <iostream>
using namespace std;

void print (const int& a)
{
    cout<<"const ref";
}

int main()
{
    print(9);   
}

我得到的输出是“const ref”

编辑: 如果我再次重写代码,这里还有一件事

#include <iostream>
using namespace std;

void print (int &&a)
{
    cout<<"rval ref";
}

void print (const int&& a)
{
    cout<<"const ref";
}

int main()
{
    print(9);   
}

还是打印“rval ref”,请说明逻辑

有人可以解释为什么 C++ 在将 ravlue 作为参数传递时优先于 && 而不是 const 吗?## 标题 ##

最佳答案

让我们逐案看看发生了什么:

案例一

这里我们考虑:

void print (int &&a)
{
    cout<<"rval ref";
}

void print (const int& a)
{
    cout<<"const ref";
}

int main()
{
    print(9); //chooses print(int&&) version  
}

案例 1 的行为可以从 over.ics.rank 中理解。其中指出:

3.2 Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if

S1 and S2 are reference bindings ([dcl.init.ref]) and neither refers to an implicit object parameter of a non-static member function declared without a ref-qualifier, and S1 binds an rvalue reference to an rvalue and S2 binds an lvalue reference.

(强调我的)

这意味着在您的案例 1 中,带有 int&& 的版本优于 const int&


案例2

这里我们考虑:

void print (const int& a)
{
    cout<<"const ref";
}

int main()
{
    print(9);   //chooses the only viable and available option print(const int&)
}

在情况 2 中,由于 const 对象的左值引用 允许绑定(bind)到右值,因此提供的 print(const int&) 是可行的,并且是唯一可用的,因此被选中。

案例三

这里我们考虑:

void print (int &&a)
{
    cout<<"rval ref";
}

void print (const int&& a)
{
    cout<<"const ref";
}

int main()
{
    print(9);   
}

现在,这选择了第一个版本 print(int&&) 因为 9 是一个 int 纯右值而不是一个 const int 右值。另请注意,对于 const int 纯右值,其 const 将在任何进一步分析之前被剥离,因此第一个版本 print(int&&) 将被选中。这是在 expr#6 中指定的:

If a prvalue initially has the type cv T, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.

这意味着对于类类型 const 纯右值函数 printprint(const C&&) 的第二个版本将被选择,这与内置 int 类型,如下所示。

struct C 
{
    C()
    {
        std::cout<<"default ctor"<<std::endl;
    }
};
void print (C &&a)
{
    cout<<"rval ref";
}

void print (const C&& a)
{
    cout<<"const ref";
}
const C func()
{
    const C temp;
    return temp;
}
int main()
{
    print(func()); //prints const ref  
}

上述程序对于类类型 C 的输出是:

default ctor
const ref

从上面的例子可以明显看出,对于类类型,将选择带有const C&& 的第二个打印版本。

关于c++ - 为什么 C++ 在函数调用时优先考虑右值引用而不是 const 引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68184575/

相关文章:

c++ - 为什么允许指向内联函数的指针?

c++ - 按值传递与按引用或指针传递的性能成本?

c++ - 为什么要返回通过引用传递给 C++ 中的函数的对象?

design-patterns - C++1 1's && (R-value reference) operator obsolete the ' 代理对象的设计模式吗?

c++ - move 构造函数和静态数组

c++ - 适用于 C++ 的其他包含路径和链接器选项 Gradle

c++ - 从一个类的对象调用方法继承自另一个类

c++ - El Capitan 下 Xcode 中的 clang-omp

c++ - 了解返回时的右值引用