C++ 对象、右值引用、常量引用之间的重载解析

C++ 对象、右值引用、常量引用之间的重载解析,c++,c++11,overloading,rvalue-reference,c++14,C++,C++11,Overloading,Rvalue Reference,C++14,考虑到这三个函数,这个调用是不明确的 int f( int ); int f( int && ); int f( int const & ); int q = f( 3 ); 删除f(int)会导致Clang和GCC都喜欢右值引用而不是左值引用。但是,相反,删除任何一个引用重载都会导致f(int)的歧义 重载解析通常按照严格偏序进行,但是int似乎等价于两个彼此不等价的事物。这里有什么规定?我似乎想起了一份关于这方面的缺陷报告 在未来的标准中,int&是否有可能优于i

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

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&
来完成,和显式复制。但我甚至不确定这是否是严格的标准

这里有什么规定

由于只有一个参数,规则是该参数的三个可行参数初始化中的一个必须比另两个更好地匹配。比较两种初始化时,要么一种优于另一种,要么两者都不优于(它们无法区分)

如果没有关于直接引用绑定的特殊规则,所提到的所有三种初始化都将无法区分(在所有三种比较中)

关于直接引用绑定的特殊规则使得
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&&之间的重载实际上意味着“如果我被赋予了所有权,就使用现有对象,否则就创建一个副本。”


您建议使引用绑定比非引用绑定更匹配。为什么不把你的想法发到网上呢。因此,这不是主观讨论/意见的最佳选择。

您在代码中陈述
int&&
,然后在问题中概括为
T&&
,尽管它们不同。这是哪一个?@Rapptz在谈到现实世界中可能的意义时,我只说了
T
。我并不是要建议完美的转发,这是一个完全不同的游戏。所以gcc和clang都是正确的:如果考虑到
f(int)
f(int&&)
,过载是不明确的,对于
f(int)
f(int const&)
@Yakk:“如果f(int)和f(int&&”)考虑到这一点,过载“几乎”是不明确的。如果没有最佳匹配,则重载是不明确的。假设
f(int)
f(int&)
f(double)
对于调用
f(2.0)
是可行的
f(double)
是最好的匹配,即使
f(int)
f(int&)
也在考虑之中。