473,320 Members | 1,881 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Should this really be a compile error?

We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:

-------------------

class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.

}

class C
{

public:
void foo();

void foo(int i);

};

void C::foo(int i)
{
foo(); // Neither compiler gives an error here.

}

---------------------

Clearly it has something to do with the inheritance, but there is a
valid foo() call in the scope of B's foo(int). If we call "A::foo()"
instead, it works without complaint.

Jul 10 '06 #1
10 1320
ro*********@gmail.com wrote:
We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:
Dunno about the Sun compiler, bug g++ 2.95 is very old. You should upgrade
it.
class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.
They are coorect.
}

class C
{

public:
void foo();

void foo(int i);

};

void C::foo(int i)
{
foo(); // Neither compiler gives an error here.
They are again correct.
}

---------------------

Clearly it has something to do with the inheritance, but there is a
valid foo() call in the scope of B's foo(int). If we call "A::foo()"
instead, it works without complaint.
That's how it's supposed to be. A function in a derived class hides all
functions of the base class that have the same name. You must either
qualify it with A::foo() or add:

using A::foo;

to B's class definition.
Jul 10 '06 #2
In article <11**********************@m73g2000cwd.googlegroups .com>,
ro*********@gmail.com wrote:
We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:

-------------------

class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.

}
'foo()' is hidden in this scope, thus the error.

class B : public A {
using foo;
public:
void foo(int i);
};

Will stop the error.
Jul 10 '06 #3
"Rolf Magnus" <ra******@t-online.dewrote in message
news:e8*************@news.t-online.com...
ro*********@gmail.com wrote:
>We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:

Dunno about the Sun compiler, bug g++ 2.95 is very old. You should upgrade
it.
>class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.

They are coorect.
>}

class C
{

public:
void foo();

void foo(int i);

};

void C::foo(int i)
{
foo(); // Neither compiler gives an error here.

They are again correct.
>}

---------------------

Clearly it has something to do with the inheritance, but there is a
valid foo() call in the scope of B's foo(int). If we call "A::foo()"
instead, it works without complaint.

That's how it's supposed to be. A function in a derived class hides all
functions of the base class that have the same name. You must either
qualify it with A::foo() or add:

using A::foo;

to B's class definition.
Why is it supposed to be like that, out of interest? What's the problem
with/disadvantage of not hiding base functions with the same name?

Cheers,
Stu
Jul 10 '06 #4
In article <11**********************@m73g2000cwd.googlegroups .com>,
ro*********@gmail.com says...
We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:
They're right.
class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.
B::foo() hides A::foo() at this point. The compiler basically
searches back through the inheritance tree only as far as necessary
to find at least one function named foo. It then attempts to select
among any overloads of the name in that scope. If it can't find a
suitable overload it does NOT search further back through the
inheritance tree for more overloads -- it stops and gives an error.

As you've already noted, explicitly qualifying your call to A::foo()
allows the compiler to find the correct function. You can also use a
using declaration to get the compiler to treat A::foo() as if it was
in the same scope as B::foo():

class B : public A {
using A::foo;
public:
void foo(int i) {
foo();
}
};

Note, however, that this applies to A::foo in general -- if A
contains several overloads of foo(), it makes _all_ of them appear
local. It doesn't bring just one of those overloads into scope.

To summarize: functions with the same name at different scopes do NOT
overload each other. Rather, the name(s) at the inner scope hide the
name(s) at the outer scope, unless you take steps to prevent them
from begin hidden. As you'd expect, code like yours in which a
function in a derived class hides a function from a base class is
generally a poor idea. It can easily (and will often) lead to
unexpected results.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 10 '06 #5
Stuart Golodetz wrote:
[..] What's the
problem with/disadvantage of not hiding base functions with the same
name?
Name hiding transcends member functions. It's more general and making
it different for classes would overcomplicate things. Have you tried
looking in D&E? I just searched in Google Groups for <"name hiding"
why classand got enough discussions to keep one busy for a day (the
double quotes are needed, the 'class' word is supposed to keep non-C++
results out). Please don't ask us to start another beating of this
dead horse.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 10 '06 #6
"Victor Bazarov" <v.********@comAcast.netwrote in message
news:e8**********@news.datemas.de...
Stuart Golodetz wrote:
>[..] What's the
problem with/disadvantage of not hiding base functions with the same
name?

Name hiding transcends member functions. It's more general and making
it different for classes would overcomplicate things. Have you tried
looking in D&E? I just searched in Google Groups for <"name hiding"
why classand got enough discussions to keep one busy for a day (the
double quotes are needed, the 'class' word is supposed to keep non-C++
results out). Please don't ask us to start another beating of this
dead horse.

V
Ok, I'll check it out. I didn't realise it had been discussed before (I
probably should have looked first, thanks for pointing it out). "By all
means leave the poor beast alone", say I :)

Ta,
Stu
Jul 10 '06 #7
Rob

Jerry Coffin wrote:
In article <11**********************@m73g2000cwd.googlegroups .com>,
ro*********@gmail.com says...
We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:

They're right.
class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.

B::foo() hides A::foo() at this point. The compiler basically
searches back through the inheritance tree only as far as necessary
to find at least one function named foo. It then attempts to select
among any overloads of the name in that scope. If it can't find a
suitable overload it does NOT search further back through the
inheritance tree for more overloads -- it stops and gives an error.

As you've already noted, explicitly qualifying your call to A::foo()
allows the compiler to find the correct function. You can also use a
using declaration to get the compiler to treat A::foo() as if it was
in the same scope as B::foo():

class B : public A {
using A::foo;
public:
void foo(int i) {
foo();
}
};

Note, however, that this applies to A::foo in general -- if A
contains several overloads of foo(), it makes _all_ of them appear
local. It doesn't bring just one of those overloads into scope.

To summarize: functions with the same name at different scopes do NOT
overload each other. Rather, the name(s) at the inner scope hide the
name(s) at the outer scope, unless you take steps to prevent them
from begin hidden. As you'd expect, code like yours in which a
function in a derived class hides a function from a base class is
generally a poor idea. It can easily (and will often) lead to
unexpected results.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Thanks for the detail (thanks to everyone else who's replied, too!).

I understand why this is happening, now. I guess I was mostly
surprised because the size of the argument lists made the call to the
base class not ambiguous at all. But thinking about it, a standard
that said "names from a base class are usually hidden, unless they are
member functions and the access of them is not ambiguous" would be
pretty silly...

I looked in my "Annotated C++ Reference Manual", and there is a little
example, mostly related to unexpected argument conversion and overload
selection. The authors pointed out that if overload selection included
methods of base classes (even far up the chain), results could be very
unexpected.

Anyway, thanks again!

Rob

Jul 10 '06 #8
In article <dM********************@pipex.net>,
sg*******@dNiOaSl.PpAiMpPeLxE.AcSoEm says...

[ ... ]
Why is it supposed to be like that, out of interest? What's the problem
with/disadvantage of not hiding base functions with the same name?
First, it's inconsistent with the rest of the language. For example:

int my_f() {
float a;
{
int a;

a = 0.0;
}
}

Here, the assignment is clearly to the int, even though the float is
a better fit with the type of '0.0'.

Let's assume we changed the rules, and considered this an assignment
to the float. The second major problem can be seen by adding 'double
a' (or 'extern double a') outside the function. Now, even though the
function itself hasn't changed at all, the meaning of the assignment
has changed completely -- it's an assignment to a different variable
entirely.

This also interacts with another rule in C++: first it resolves
names, then it checks access. That means (for example) if you add a
variable in a base class, it participates in overload resolution the
same whether it's private, public or protected. IOW, adding almost
any name in the base class would potentially affect the results in
all derived classes, even if the base class name as private, so the
derived classes couldn't access it.

Such a change would make it nearly impossible to maintain the base
class. Nearly any change in the base class would require intimate
knowledge of all derived classes. A seemingly minor change in the
base class might completely change the meaning of code in some
derived classes, while rendering others completely illegal.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 10 '06 #9
"Jerry Coffin" <jc*****@taeus.comwrote in message
news:MP************************@news.sunsite.dk...
In article <dM********************@pipex.net>,
sg*******@dNiOaSl.PpAiMpPeLxE.AcSoEm says...

[ ... ]
>Why is it supposed to be like that, out of interest? What's the problem
with/disadvantage of not hiding base functions with the same name?

First, it's inconsistent with the rest of the language. For example:

int my_f() {
float a;
{
int a;

a = 0.0;
}
}

Here, the assignment is clearly to the int, even though the float is
a better fit with the type of '0.0'.

Let's assume we changed the rules, and considered this an assignment
to the float. The second major problem can be seen by adding 'double
a' (or 'extern double a') outside the function. Now, even though the
function itself hasn't changed at all, the meaning of the assignment
has changed completely -- it's an assignment to a different variable
entirely.

This also interacts with another rule in C++: first it resolves
names, then it checks access. That means (for example) if you add a
variable in a base class, it participates in overload resolution the
same whether it's private, public or protected. IOW, adding almost
any name in the base class would potentially affect the results in
all derived classes, even if the base class name as private, so the
derived classes couldn't access it.

Such a change would make it nearly impossible to maintain the base
class. Nearly any change in the base class would require intimate
knowledge of all derived classes. A seemingly minor change in the
base class might completely change the meaning of code in some
derived classes, while rendering others completely illegal.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Thanks, that makes sense now you put it like that :)

Cheers,
Stu
Jul 10 '06 #10
ro*********@gmail.com wrote:
We ran into this problem and I can't see why the compilers (Sun One
Studio 8 and g++ 2.95) think it's an error:

-------------------

class A
{
public:
void foo();

};

class B : public A
{
public:
void foo(int i);

};

void B::foo(int i)
{
foo(); // Both compilers give an error here.

}

class C
{

public:
void foo();

void foo(int i);

};

void C::foo(int i)
{
foo(); // Neither compiler gives an error here.

}

---------------------

Clearly it has something to do with the inheritance, but there is a
valid foo() call in the scope of B's foo(int). If we call "A::foo()"
instead, it works without complaint.
Others have answered this very well, but this is also in the FAQ:
http://www.parashift.com/c++-faq-lit....html#faq-23.9

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jul 12 '06 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Familie Spies | last post by:
Hi all, When running a program I made in VB under Windows XP i'm getting the following error: ! Compile error. Can't find project or library. (see also http://home.kabelfoon.nl/~hspies/2.jpg ) ...
7
by: Ensoul Chee | last post by:
I used #include <iostream.h> int m; cout << "Hexadecimal == 0x" << hex << m << endl; to print value of m in hexadecimal mode. But I got the compile error like this couttest.cpp:20 `hex'...
5
by: xuatla | last post by:
Hi, I encountered the following compile error of c++ and hope to get your help. test2.cpp: In member function `CTest CTest::operator+=(CTest&)': test2.cpp:79: error: no match for 'operator='...
3
by: David | last post by:
Hi, why I have compile error as follows? r.cpp: In function `int main ()': r.cpp:40: call of overloaded `change(Demo &)' is ambiguous r.cpp:11: candidates are: void Demo::change (Demo)...
4
by: Danny Boelens | last post by:
Hi all, today I ran into a compile error after a compiler upgrade. I made a small example to demonstrate my compile error: template<typename T1, typename T2> class A {}; class B
8
by: Vavel | last post by:
Hi all! I used google, but I found nothing. I have got smiple code: #include <sql.h> int main() { } when I compiled this in Borland C++ 5.5.1 for Win32 Copyright (c) 1993,
10
by: Chris LaJoie | last post by:
Our company has been developing a program in C# for some time now, and we haven't had any problems with it, but just last night something cropped up that has me, and everyone else, stumped. I...
3
by: Peter | last post by:
Hi, I am trying to compile an existing project (originally c) in .NET (rename .c files to .cpp). After fixing some problems, here are the ones that I don't know how to deal with:...
1
by: Bob | last post by:
Hi all, I've created a database at work and have copied it to home but have had some problems when I try to open the main form. The error when I run it is: Compile error: Can't find project...
17
by: MLH | last post by:
I have tested the following in immed window: ?isnumeric(1) True ?isnumeric(1.) True ?isnumeric(1.2) True ?isnumeric(1.2.2)
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.