在学习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);
}
在这两个例子中,编译器抱怨重载函数的调用&#34; g(double)&#34;很暧昧。
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);
}
但是在这个例子中,程序正确编译并打印出&#34; void g(const double&amp;&amp;)&#34;。 所以我不明白为什么编译器会抱怨前两个例子但不是第三个例子。
答案 0 :(得分:3)
在重载决策中,直接引用绑定是身份转换(即使添加了限定符); double
匹配参数double
或引用 - double
不会更好或更糟。
const
在你的例子中有点像红色鲱鱼。对于非引用类型f(const double)
,顶级const
不是函数签名的一部分;在f(const double&)
中,它仍然是直接绑定,因此仍然是身份转换。
所以,你的前两个案例都是两种情况下的身份转换,没有理由偏好其中一种。
在案例3中,规则C ++ 14 [over.ics.rank] /3.1.3适用:
标准转换序列S1是比标准转换序列更好的转换序列 S2如果
- [...]
- S1和S2是引用绑定(8.5.3),并且都不引用a的隐式对象参数 在没有ref-qualifier的情况下声明的非静态成员函数,S1将rvalue引用绑定到rvalue,S2绑定左值引用。
此规则允许为相同类型的rvalues和lvalues重载函数。
答案 1 :(得分:2)
此表总结了谁可以去哪里:
---------------------------------------------------------------------------------
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)
---------------------------------------------------------------------------------