为什么C++在函数调用时优先选择右值引用而不是常量引用



所以我用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引用";但如果我重写代码只是删除一个函数定义:

#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++偏爱&amp;传递ravalue作为参数时超过const?##标题##

让我们逐个查看发生了什么:

情况1

这里我们考虑:

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如果,标准转换序列S1是比标准转换序列S2更好的转换序列

S1S2是引用绑定([dcl.init.ref](,两者都不引用在没有ref限定符的情况下声明的非静态成员函数的隐式对象参数,并且S1将右值引用绑定到右值,S2将左值引用绑定

(强调矿(

这意味着在本例1中,与const int&相比,具有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对象的左值引用绑定到右值,因此所提供的print(const int&)是可行的,并且是唯一可用的,因此被选择。

情况3

这里我们考虑:

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

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

如果一个prvalue最初具有类型cv T,其中T是cv不合格的非类、非数组类型,则在进行任何进一步分析之前,表达式的类型将调整为T

这意味着对于类类型constprvalues,将选择具有print(const C&&)的函数print的第二个版本,这与内置类型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&&的第二个打印版本。

最新更新