提问人:simplekind 提问时间:6/30/2021 最后编辑:user438383simplekind 更新时间:5/25/2022 访问量:341
为什么 C++ 在函数调用时优先使用右值引用而不是常量引用?[复制]
Why does C++ give preference to rvalue reference over const reference while function call? [duplicate]
问:
所以我用 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 refernce” 但是,如果我重写代码,只是删除一个函数定义:
#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 吗?## 标题##
答:
让我们根据具体情况看看发生了什么:
案例 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
更好的转换序列
S1
并且是引用绑定 ([dcl.init.ref]),并且两者都不引用没有 ref 限定符声明的非静态成员函数的隐式对象参数,并且 S1
将右值引用绑定到右值,S2
绑定左值引用。S2
(强调我的)
这意味着在本例 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
对象的左值引用绑定到右值,因此提供的是可行的,并且是唯一可用的,因此被选中。print(const int&)
案例 3
在这里,我们考虑:
void print (int &&a)
{
cout<<"rval ref";
}
void print (const int&& a)
{
cout<<"const ref";
}
int main()
{
print(9);
}
现在,它选择第一个版本,因为这是一个 prvalue 而不是 prvalue。另请注意,对于 prvalue,它将在进行任何进一步分析之前被剥离,因此将选择第一个版本。这是在 expr#6 中指定的:print(int&&)
9
int
const int
const int
const
print(int&&)
如果 prvalue 最初具有 类型 ,其中 是 cv 非限定的非类、非数组类型,则在进行任何进一步分析之前,表达式的类型将调整为
T
。cv T
T
这意味着对于类类型 prvalues,将选择函数的第二个版本,这与如下所示的内置类型不同。const
print
print(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
从上面的例子中可以明显看出,对于类类型,将选择第二个版本的print with。const C&&
评论
9
int
const int
int
const
const int
const
print
int&&
print
评论
9
9