Re: Can someone explain this substitution? Organization: Arcor
"Jeremy" <bjeremy32@yahoo.com> schrieb im Newsbeitrag news:76d6884c-cab3-494d-9bc6-884cdb371704@w21g2000yqm.googlegroups.com...
I think this problem maybe some part of the Liskov Substitution
Principle or Keonig lookup. Below is some code that demonstrates it.
[sniping code]
class BaseIf
{
public:
virtual void display(int x, bool y=true) = 0;
[snipping code]
class Base : public BaseIf
{
public:
void display(index1 x, bool y) {std::cout << "display(int) :" << x
<< std::endl; }
Note the default argument to the second parameter of BaseIf::display( int,
bool ). The virtual override in Base doesn't have one, and this is the cause
of your problem.
void display (intLike x) {std::cout << "display(intLike) :" << x
<< std::endl; }
void display (intLikeToo x) {std::cout << "display(intLikeToo) :"
<< x << std::endl; }
// This method will result in an ambigous function call
// void fun(){ display(2);}
};
int main()
{
BaseIf * b = new Base;
b->display(2);
// This call will result in an ambiguous function call
//b->fun();
return 0;
}
[snip]
Step 3: This is where I am having a problem, if I uncomment
display(int) and add another method to Base called fun(), and fun()
simply calls display(2), I again receive the ambiguous overloaded
method error.
If you call display( 2 ) from within a member function of BaseIf, then the
compiler sees the default argument and picks BaseIf::display( int, bool ),
but if you call display( 2 ) from within a member function of Base, then the
default argument is missing, so the compiler cannot pick Base::display( int,
bool ) because there are not enough argument. So the compiler has to choose
between the other two overlaods, which is ambiguous.
So why is it ok to call display(2) from main(), but I end up getting a
compile error if I call display(2) from within the class itself? I
would have expected that if Step 1 compiled fine, then Step 3 would
have also compiled fine.
Simply add the same default argument to Base::display( int, bool ) and you
will get what you expect:
class Base : public BaseIf
{
public:
// Note that default argument to the second parameter.
void display(index1 x, bool y=true) {std::cout << "display(int) :" << x
<< std::endl; }
void display (intLike x) {std::cout << "display(intLike) :" << x
<< std::endl; }
void display (intLikeToo x) {std::cout << "display(intLikeToo) :"
<< x << std::endl; }
// Now this compiles fine.
void fun(){ display(2);}
};
Default arguments are resolved statically. As you have already noticed, this
can lead to unexpected results, so you should make sure that default
arguments in virtual functions are always identical.
--
Matthias Hofmann
Anvil-Soft, CEO
http://www.anvil-soft.com - The Creators of Toilet Tycoon
http://www.anvil-soft.de - Die Macher des Klomanagers
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]