C ++ nonconst-const引用函数重载

时间:2013-11-26 17:17:24

标签: c++ g++ pass-by-reference lvalue rvalue

在以下代码中:

int foo(const int& f) //version 1
{
    int g = f;
    return int(foo(g)); // calls itself, turning into SO
}

int& foo(int& f) //version 2
{
    f *= -1;
    return f;
}

int main()
{
    int f = 11;
    cout << foo(f) << endl;
    cout << foo(22) << endl;
}

第一个cout按预期打印-11; f是左值,因此它绑定到 foo 的第二个版本(虽然它也可以绑定到第一个版本,第二个版本它是更好的匹配)。

foo的第二次调用是使用右值作为参数,因此唯一可行的foo版本是第一个。到现在为止还挺好。在foo的第一个版本中,我制作了参数的副本,因此我可以调用第二个版本(带有左值)并在调用第二个版本后返回它的副本foo。事情是这会变成堆栈溢出;仍然会调用foo的第一个版本。

有人可以向我解释为什么会这样吗?我希望g的第一个版本中的foo在作为参数传递时绑定到foo的第二个版本。

3 个答案:

答案 0 :(得分:10)

这很简单 - foo此时仅表示foo(const int& f)。没有第二选择。还没。切换定义。或者将它们分开:

int foo(const int& f);
int& foo(int& f);

int main()
{
    int f = 11;
    cout << foo(f) << endl;
    cout << foo(22) << endl;
}


int foo(const int& f) //version 1
{
    int g = f;
    return int(foo(g)); // calls itself, turning into SO
}

int& foo(int& f) //version 2
{
    f *= -1;
    return f;
}

答案 1 :(得分:2)

foo的第一个声明不知道第二个的存在。试试这个:

int foo(int& f);
int foo(const int& f) //version 1
{
    int g = f;
    return int(foo(g)); // calls itself, turning into SO
}

答案 2 :(得分:1)

编译器到达行时:

return int(foo(g))

它不知道您的重载版本2.将原型声明添加到文件的顶部:

int foo(const int& f);
int& foo(int& f);

这样编译器就会知道版本2是否存在,并且可以在编写foo时调用它。