所以我用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
纯右值函数 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
从上面的例子可以明显看出,对于类类型,将选择带有const C&&
的第二个打印版本。