值、右值引用、const 左值引用之间的重载解析

问题描述 投票:0回答:1

考虑到所有三个函数,这个调用是不明确的。

int f( int );
int f( int && );
int f( int const & );

int q = f( 3 );

删除

f( int )
会导致 Clang 和 GCC 更喜欢右值引用而不是左值引用。但删除任一引用重载都会导致
f( int )
产生歧义。

重载解析通常是按照严格的部分排序来完成的,但是

int
似乎相当于两个彼此不等价的东西。这里有什么规则?我好像记得有一个关于这个的缺陷报告。

在未来的标准中,

int &&
是否有可能比
int
更受青睐?引用必须绑定到初始值设定项,而对象类型则不受此限制。因此,
T
T &&
之间的重载实际上意味着“如果我已被授予所有权,则使用现有对象,否则进行复制。” (这类似于纯值传递,但节省了移动的开销。)由于这些编译器当前正在工作,因此必须通过重载
T const &
T &&
并显式复制来完成。但我什至不确定这是否是严格的标准。

c++ c++11 overloading rvalue-reference c++14
1个回答
65
投票

这里有什么规则?

由于只有一个参数,因此规则是该参数的三个可行参数初始化之一必须比其他两个“更好匹配”。当比较两个初始化时,其中一个比另一个更好,或者都不是更好(它们是无法区分的)。 如果没有关于直接引用绑定的特殊规则,提到的所有三个初始化将无法区分(在所有三个比较中)。 有关直接引用绑定的特殊规则使

int&&

优于

const int&

,但两者都不比

int
更好或更差。因此不存在最佳匹配:

S1 S2 int int&& indistinguishable int const int& indistinguishable int&& const int& S1 better

int&&
const int&

更好,因为 13.3.3.2:


S1 和 S2 是引用绑定(8.5.3),并且都不引用未使用 ref 限定符声明的非静态成员函数的隐式对象参数,并且 S1 将右值引用绑定到右值,S2 绑定左值引用。 

但是当初始化之一不是引用绑定时,此规则不适用。

在未来的标准中,int && 是否有可能比 int 更受青睐?引用必须绑定到初始值设定项,而对象类型则不受此限制。因此,T 和 T && 之间的重载实际上意味着“如果我被授予所有权,则使用现有对象,否则制作一个副本。”

您建议使引用绑定比非引用绑定更匹配。为什么不将您的想法发布到

isocpp未来提案

。 SO 并不是主观讨论/意见的最佳选择。

© www.soinside.com 2019 - 2024. All rights reserved.