Reputation: 321
In the following code:
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;
}
The first cout prints -11 as expected; f is a lvalue, so it binds to the second version of foo (although it could bind to 1st version as well, the 2nd version it's a better match).
The second call of foo
is using a rvalue as parameter, so the only viable version of foo
is the first one. So far, so good. Inside the first version of foo
, I made a copy of the parameter so I could call the second version (with a lvalue) and return a copy of it after the call of the second version of foo
. The thing is this will turn into a stack overflow; still the first version of foo
will be called.
Could someone please explain to me why this happens? I would expect that g
inside the first version of foo
to bind to the second version of foo
when passed as parameter.
Upvotes: 6
Views: 121
Reputation: 62472
When the compiler reaches the line:
return int(foo(g))
It doesn't know about your overloaded version 2. Add prototype declarations to the top of the file:
int foo(const int& f);
int& foo(int& f);
This way the compiler will know about the existence of version 2 and can consider it when working out whith foo
to call.
Upvotes: 1
Reputation: 6505
The first declaration of foo has no idea about the existence of the second one. Try this:
int foo(int& f);
int foo(const int& f) //version 1
{
int g = f;
return int(foo(g)); // calls itself, turning into SO
}
Upvotes: 3
Reputation: 258568
It's simple really - foo
at that point only means foo(const int& f)
. There's no second choice. Not yet. Switch up the definitions. Or separate them:
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;
}
Upvotes: 11