From: nomad on
Anyone have any idea why the code below fails to compile? I get the following
message when I try:

error C2660: 'B::F' : function does not take 2 arguments.'

Clearly, B should inherit int F(int, int) from A, the function declaration
is not ambiguous in any way, so it seems to me that I should be able to call
it, yet the compiler refuses to allow me to do it. If I explicitly reference
it (i.e., A::F(x, 3) instead of this->F(x, 3)), it works fine.

class A
{
public:
A(void) { };
virtual int F(int x) = 0;

protected:
int F(int x, int y)
{
return x + y;
}
};

class B : public A
{
public:
B(void) { };

virtual int F(int x)
{
return this->F(x, 3);
}
};

int main(void)
{
B b;

(void) b.F(3);
}

From: Alf P. Steinbach on
* nomad:
> Anyone have any idea why the code below fails to compile? I get the following
> message when I try:
>
> error C2660: 'B::F' : function does not take 2 arguments.'
>
> Clearly, B should inherit int F(int, int) from A, the function declaration
> is not ambiguous in any way, so it seems to me that I should be able to call
> it, yet the compiler refuses to allow me to do it. If I explicitly reference
> it (i.e., A::F(x, 3) instead of this->F(x, 3)), it works fine.

This is a FAQ (see below).


> class A
> {
> public:
> A(void) { };
> virtual int F(int x) = 0;
>
> protected:
> int F(int x, int y)
> {
> return x + y;
> }
> };
>
> class B : public A
> {
> public:
> B(void) { };
>
> virtual int F(int x)
> {
> return this->F(x, 3);
> }
> };
>
> int main(void)

This 'void' is a C-ism. Not that it matters much, just a fine detail.

> {
> B b;
>
> (void) b.F(3);

This cast is completely unnecessary.

> }

For your question about why you get a compilation error, see the FAQ
item titled "What's the meaning of, Warning: Derived::f(char) hides
Base::f(double)?", currently item 23.9, available at e.g. <url:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9>,
or any mirror.

It's often a good idea to check the FAQ first.


Cheers, & hth.,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
From: nomad on
> > (void) b.F(3);
>
> This cast is completely unnecessary.

True, but I like to indicate that I know there's a return value but that I'm
explicitly ignoring it.

> For your question about why you get a compilation error, see the FAQ
> item titled "What's the meaning of, Warning: Derived::f(char) hides
> Base::f(double)?", currently item 23.9, available at e.g. <url:
> http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9>,
> or any mirror.

Well, I checked the FAQ for inheritance issues, but missed that one. If the
compiler had given me a 'derived f(char) hides base::f(double)' error, I'd've
known what was going on. I'd forgotten about C++'s silly failure to resolve
overloads across scopes.

Thanks for the pointer.

From: Alf P. Steinbach on
* nomad:
>>> (void) b.F(3);
>> This cast is completely unnecessary.
>
> True, but I like to indicate that I know there's a return value but that I'm
> explicitly ignoring it.
>
>> For your question about why you get a compilation error, see the FAQ
>> item titled "What's the meaning of, Warning: Derived::f(char) hides
>> Base::f(double)?", currently item 23.9, available at e.g. <url:
>> http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.9>,
>> or any mirror.
>
> Well, I checked the FAQ for inheritance issues, but missed that one. If the
> compiler had given me a 'derived f(char) hides base::f(double)' error, I'd've
> known what was going on.

Yes, I notice that neither MSVC nor g++ produce that warning, which
would have been good.


> I'd forgotten about C++'s silly failure to resolve
> overloads across scopes.

It's not a failure, it's an intentional design decision.

Either way there are (non-obvious) problems, which means that either
way the behavior is a little counter-intuitive.

The language designer and the committee believed that this design
choice minimized the problems, but unfortunately it's also the most
counter-intuitive, at least judging from Usenet questions about it...


> Thanks for the pointer.

You're welcome.


Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
From: Vladimir Grigoriev on
"nomad" <nomad(a)discussions.microsoft.com> wrote in message
news:BA8C8156-5F14-413A-BC1B-E195B94C5A2A(a)microsoft.com...
> Anyone have any idea why the code below fails to compile? I get the
> following
> message when I try:
>
> error C2660: 'B::F' : function does not take 2 arguments.'
>
> Clearly, B should inherit int F(int, int) from A, the function declaration
> is not ambiguous in any way, so it seems to me that I should be able to
> call
> it, yet the compiler refuses to allow me to do it. If I explicitly
> reference
> it (i.e., A::F(x, 3) instead of this->F(x, 3)), it works fine.
>
> class A
> {
> public:
> A(void) { };
> virtual int F(int x) = 0;
>
> protected:
> int F(int x, int y)
> {
> return x + y;
> }
> };
>
> class B : public A
> {
> public:
> B(void) { };
>
> virtual int F(int x)
> {
> return this->F(x, 3);
> }
> };
When the compiler finds the name F it tries resolve it inside the class
scope. The class B has only one function with name F which accepts only one
parameter. So the compiler signals an error. When you specify explicitly
A::F( x, 3 ) the compiler knows which function to use.
You can make that the function F with two parameters become visible by
including its name in the scope of class B as the following

class B: public A

{

public:

virtual int F( int x )

{

return this->F( x, 3 );

}

protected:

using A::F;

};


Vladimir Grigoriev