C++-编译器如何决定使用引用类型作为参数的重载函数?

在学习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)
    ---------------------------------------------------------------------------------
  • 以上所有签名都可以共存。
  • V符号标记可能的有效解决方案
  • 如果同一调用方有多个有效解析,则会对它们进行编号,(1)比(2)更匹配,依此类推。
  • 使用上述任何一项重载val版本都没有意义,除非在方法上有其他差异,如const等。 添加BYVALE版本:F(X X)不能很好地与以上任何组合一起使用-在大多数情况下,它会导致任何调用的模糊性,对于某些情况,它只会更喜欢BYVAL版本(如果它只与[a]一起存在-除lvalue之外的任何调用都将首选BYVALE版本,而lvalue调用将导致歧义)。
  • 签名[d]很少使用,请参阅:Do rvalue references to const have any use?

相关文章