在研究C 时,我遇到了复杂的转换序列主题,并且我遇到了一个无法独自解决的问题。
void g(const double)
{
std::cout << "void g(const double)" << std::endl;
}
void g(const double&&)
{
std::cout << "void g(const double&&)" << std::endl;
}
int main(int argc, char **argv)
{
g(3.14);
return (0);
}
态------------
void g(const double)
{
std::cout << "void g(const double)" << std::endl;
}
void g(const double&)
{
std::cout << "void g(const double&)" << std::endl;
}
int main(int argc, char **argv)
{
g(3.14);
return (0);
}
在这两个示例中,编译器抱怨过载函数" G(double)"的呼叫是模棱两可的事实。
void g(const double&&)
{
std::cout << "void g(const double&&)" << std::endl;
}
void g(const double&)
{
std::cout << "void g(const double&)" << std::endl;
}
int main(int argc, char **argv)
{
g(3.14);
return (0);
}
但是在此示例中,程序正确编译并打印出" void g(const double&amp;&amp;)"。因此,我不明白为什么编译器抱怨前两个示例,但没有第三个示例。
超载分辨率表
此表总结了谁可以去哪里:
---------------------------------------------------------------------------------
Caller | lvalue | const lvalue | rvalue | const rvalue
Function | | | |
---------------------------------------------------------------------------------
[a] f(X& x) | V (1) | | |
---------------------------------------------------------------------------------
[b] f(const X& x) | V (2) | V | V (3) | V (2)
---------------------------------------------------------------------------------
[c] f(X&& x) | | | V (1) |
---------------------------------------------------------------------------------
[d] f(const X&& x) | | | V (2) | V (1)
---------------------------------------------------------------------------------
- 上述所有签名都可以一起生活。
- V 标志标记可能有效的分辨率
- 当相同的呼叫者有多个有效分辨率时,(1)比(2)等更好匹配
- 除非有其他差异,例如方法等等,否则与上述任何一个差异都没有任何意义。添加字节版本:f(x x)与上述任何组合都无法正常工作 - 在大多数情况下,对于任何调用,都会产生歧义性,在某些情况下,它只会更喜欢Byval版本(如果仅与[a]生存 - 除了lvalue以外的任何调用都会更喜欢Byvalue版本,并且LVALUE调用将带有歧义)。
- 签名[D]很少使用,请参阅:rvalue引用对const有任何用途吗?
在过载分辨率中,直接引用绑定是 sendentity conversion (即使添加了预选赛);double
匹配double
或参考到double
的参数不是更好或更糟的。
在您的示例中,const
在某种程度上有点红鲱鱼。对于非参考类型,f(const double)
,顶级const
不是函数签名的一部分;在f(const double&)
中,它仍然是直接的绑定,因此仍然是身份转换。
因此,您的前2个情况都是在两种情况下既是身份转换,又不偏爱一个或另一个情况。
在情况3中,规则C 14 [over.ics.rank]/3.1.3适用:
标准转换序列S1比标准转换序列更好 S2如果
- [...]
- s1和s2是参考绑定(8.5.3),两者都不是指一个隐式对象参数 无静态成员函数在没有参考值的情况下声明,S1与RVALUE参考结合了RVALUE,S2结合了LVALUE参考。
此规则允许对同一类型的RVALUE和LVALUE的功能过载。