在学习 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&&)”。
所以我不明白为什么编译器会抱怨前两个例子,但不会抱怨第三个例子。
过载解决表
下表总结了谁可以去哪里:
---------------------------------------------------------------------------------
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)
---------------------------------------------------------------------------------
- 以上所有签名都可以共存。
- The V符号标记可能的有效分辨率
- 当同一呼叫者有多个有效解决方案时,它们会被编号,(1) 比 (2) 更匹配,等等。
- 使用上述任何版本重载 byval 版本都是没有意义的,除非有其他差异,例如方法上的 const 等。
添加按值版本: f(X x) 不适用于上述任何组合 - 在大多数情况下,它会导致歧义对于任何调用,在某些情况下,它只会更喜欢 byval 版本(如果它仅与 [a] 一起存在 - 除左值之外的任何调用都会更喜欢 byvalue 版本,并且左值调用将导致歧义).
- 签名[d]很少使用,参见:const 的右值引用有什么用吗?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)