|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Feel free to redirect me to a better place to ask if you know of one.
The following code will not compile: class foo{}; class A{ public: void f(int a ){a++;}; private: virtual void f(foo a) = 0; }; class B : public A{ private: virtual void f(foo a){}; }; int main(){ B b; int a=0; b.f(a); } The problem seems to be that all of my functions being named f are somehow colliding with each other. It seems to me that the call b.f(a) is unambiguosly pointing to A::f(int), but gcc disagrees. I can fix this if I namespace the b.f(a) call, but that's a little ugly. I can also fix it if I put a forwarding function inside B that calls the proper function inside A, also a little ugly. I could also mangle my functions' names, but I really feel that's the compiler's job, not mine, especially since I think I already provided enough context with a function signature. If a using declaration should be enough to fix this, where should I place? Or a better fix? Thanks, - Jordi G. H. -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Wed May 21 2008 19:00:27 Jordi Gutiérrez Hermoso wrote:
> The problem seems to be that all of my functions being named f are > somehow colliding with each other. Annotated C++ Reference Manual, Ellis & Stroustrup, Section 13.1 (Declaration Matching). "A function member of a derived class is not in the same scope as a function member of the same name in a base class." --Mike Bird -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On 21/05/2008, Mike Bird <mgb-debian@yosemite.net> wrote:
> On Wed May 21 2008 19:00:27 Jordi Gutiérrez Hermoso wrote: > > The problem seems to be that all of my functions being named f are > > somehow colliding with each other. > > > Annotated C++ Reference Manual, Ellis & Stroustrup, Section 13.1 > (Declaration Matching). "A function member of a derived class is > not in the same scope as a function member of the same name in a > base class." So what's the fix here? Why does a using A::f declaration inside class B not work? - Jordi G. H. -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Wed May 21 2008 20:01:10 Jordi Gutiérrez Hermoso wrote:
> On 21/05/2008, Mike Bird <mgb-debian@yosemite.net> wrote: > > On Wed May 21 2008 19:00:27 Jordi Gutiérrez Hermoso wrote: > > > The problem seems to be that all of my functions being named f are > > > somehow colliding with each other. > > > > Annotated C++ Reference Manual, Ellis & Stroustrup, Section 13.1 > > (Declaration Matching). "A function member of a derived class is > > not in the same scope as a function member of the same name in a > > base class." > > So what's the fix here? Why does a using A::f declaration inside class > B not work? There's no f(int) in scope, only int(foo). You could always switch to A's scope: dynamic_cast<A*>(&b)->f(a); But the best solution is to read up on WHY C++ works this way so you can understand the implications that thousands of great minds have already pondered. --Mike Bird -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Wednesday 21 May 2008, Jordi Gutiérrez Hermoso wrote:
> The following code will not compile: > > class foo{}; > > class A{ > public: > void f(int a ){a++;}; > private: > virtual void f(foo a) = 0; > }; > > class B : public A{ > private: > virtual void f(foo a){}; > }; > > int main(){ > B b; > int a=0; > b.f(a); > } > > The problem seems to be that all of my functions being named > f are somehow colliding with each other. It seems to me that > the call b.f(a) is unambiguosly pointing to A::f(int), but > gcc disagrees. You might as well have written: class A{ public: void f(int a ){a++;}; }; class B : public A{ private: virtual void f(foo a){}; }; f in B has the same name as f in A but different args. This is usually a mistake, so they made it illegal. If you override one f, you need to override them all. (or change the name) To fix: class B : public A{ public: void f(int a){A::f(a);} private: virtual void f(foo a){}; }; Now, try this: class A{ private: virtual void f(foo a)=0; }; class B : public A { private: virtual void f(foo a){} }; This doesn't work either, because f in A is private, so B doesn't know it exists. I don't know what it will do. I think you get 2 f's, and still can't make an instance of B because f is pure virtual. Change the private in A to protected, so B will see it. It really is off topic.... -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Mike Bird wrote:
> On Wed May 21 2008 20:01:10 Jordi Gutiérrez Hermoso wrote: >> On 21/05/2008, Mike Bird <mgb-debian@yosemite.net> wrote: >>> On Wed May 21 2008 19:00:27 Jordi Gutiérrez Hermoso wrote: >>> > The problem seems to be that all of my functions being named f are >>> > somehow colliding with each other. >>> >>> Annotated C++ Reference Manual, Ellis & Stroustrup, Section 13.1 >>> (Declaration Matching). "A function member of a derived class is >>> not in the same scope as a function member of the same name in a >>> base class." >> So what's the fix here? Why does a using A::f declaration inside class >> B not work? > > There's no f(int) in scope, only int(foo). > Which... the compiler kindly tells us: do_foo.cpp: In function 'int main()': do_foo.cpp:18: error: no matching function for call to 'B::f(int&)' do_foo.cpp:12: note: candidates are: virtual void B::f(foo) make: *** [do_foo.o] Error 1 Hugo > You could always switch to A's scope: > > dynamic_cast<A*>(&b)->f(a); > > But the best solution is to read up on WHY C++ works this way so > you can understand the implications that thousands of great minds > have already pondered. > -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On 21/05/2008, Mike Bird <mgb-debian@yosemite.net> wrote:
> On Wed May 21 2008 20:01:10 Jordi Gutiérrez Hermoso wrote: > > > So what's the fix here? Why does a using A::f declaration inside class > > B not work? > > > There's no f(int) in scope, only int(foo). No, no, wait. This makes no sense. Consider class foo{}; class A{ public: void f(int a ){a++;}; private: virtual void f(foo a) = 0; }; class B : public A{ public: using A::f; private: virtual void f(foo a){}; }; int main(){ B b; int a=0; b.f(a); } versus class foo{}; class A{ public: void f(int a ){a++;}; public: virtual void f(foo a) = 0; }; class B : public A{ public: using A::f; public: virtual void f(foo a){}; }; int main(){ B b; int a=0; b.f(a); } The *only* thing that changed is the access specifiers. For some reason, the name lookup works and it seems that the compiler understands that "using A::f" means "A::f(int)" when some function is public but fails when the function is private, and tries instead to interpret "using A::f" as "A::f(C)". The first example fails to compile, but the second one does. > But the best solution is to read up on WHY C++ works this way so > you can understand the implications that thousands of great minds > have already pondered. Well, those great minds seem to be too great for me to fathom, because I really don't see why it seems here that a function's signature isn't enough to specify it, and they saw it fit to make sure I couldn't both I overload and inherit three related but different functions. C++ isn't perfect, the standard isn't gospel, and I'm beginning to suspect a bug in gcc. - Jordi G. H. -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Thu May 22 2008 06:34:27 Jordi Gutiérrez Hermoso wrote:
> On 21/05/2008, Mike Bird <mgb-debian@yosemite.net> wrote: > > On Wed May 21 2008 20:01:10 Jordi Gutiérrez Hermoso wrote: > > > So what's the fix here? Why does a using A::f declaration inside class > > > B not work? > > > > There's no f(int) in scope, only int(foo). > > No, no, wait. This makes no sense. Consider (two example programs snipped) > The *only* thing that changed is the access specifiers. For some > reason, the name lookup works and it seems that the compiler > understands that "using A::f" means "A::f(int)" when some function is > public but fails when the function is private, and tries instead to > interpret "using A::f" as "A::f(C)". The first example fails to > compile, but the second one does. The first thing to note is that neither of these is your original example, so it would be better if you had written "the *only* difference between the two examples above is the access specifiers". You then complain that it doesn't work when you try to "using" a private function. Had you quoted the compiler's message to you, which was probably "error: ‘virtual void A::f(foo)’ is private", it would be immediately obvious that EITHER you know nothing of C++ INCLUSIVE OR you're deliberately wasting bandwidth on this list. > > But the best solution is to read up on WHY C++ works this way so > > you can understand the implications that thousands of great minds > > have already pondered. > > Well, those great minds seem to be too great for me to fathom, because > I really don't see why it seems here that a function's signature isn't > enough to specify it, and they saw it fit to make sure I couldn't both > I overload and inherit three related but different functions. Exactly. Overload ambiguities are resolved in scope, not beyond. > C++ isn't perfect, the standard isn't gospel, and I'm beginning to > suspect a bug in gcc. Please stop now. Thousands of people, some of them much smarter than you or I, have not only decided that C++ should do this (which could be a bug) but explained at great length and in great detail why C++ works this way (thus showing that it is not a bug). You have been given a precise reference to a good example of such an explanation but you ignore it. This was offtopic anyway. Please do your homework and then if you still have questions address them to a C++ forum. --Mike Bird -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#9 |
|
Messages: n/a
Hébergeur: |
On 22/05/2008, Mike Bird <mgb-debian@yosemite.net> wrote:
> On Thu May 22 2008 06:34:27 Jordi Gutiérrez Hermoso wrote: > > The first thing to note is that neither of these is your original > example, so it would be better if you had written "the *only* > difference between the two examples above is the access specifiers". The only difference is I added a "using A::f" > You then complain that it doesn't work when you try to "using" a > private function. No, I am "using" a function that is both overloaded to private and public. But the compiler gets confused depending on the access specifier. Why should it attempt to use the private function when the access specifier is public but will happily use the public function when the access specifier is public? You keep talking about scope. The access specifier should affect scope and name resolution? This does not make sense! The public function is available, a using declaration should bring that function from A's scope into B's scope, but the compiler tries to resolve the call "b.f(a)" call to the inaccessible private function anyways. Why should this make sense? For the record, both of the snippets above compile on the Comeau C++ compiler, furthering my suspicion that this is a gcc bug. > Had you quoted the compiler's message to you, > which was probably "error: 'virtual void A::f(foo)' is private", I thought you could easily run the programs yourself and see the compiler error for yourself. > it would be immediately obvious that EITHER you know nothing of C++ > INCLUSIVE OR you're deliberately wasting bandwidth on this list. No, I'm just loudmouthed, just as much as you are, and I yell a little less, too ;-) > > > But the best solution is to read up on WHY C++ works this way so > > > you can understand the implications that thousands of great minds > > > have already pondered. > > > > Well, those great minds seem to be too great for me to fathom, because > > I really don't see why it seems here that a function's signature isn't > > enough to specify it, and they saw it fit to make sure I couldn't both > > I overload and inherit three related but different functions. > > > Exactly. Overload ambiguities are resolved in scope, not beyond. Why do g++ and Comeau disagree here? Shouldn't the using declaration bring A's functions into scope? Why is it that supposedly bringing them into scope still results in g++ trying to call the inaccessible private function and that making that inaccessible private function public suddenly results in g++ calling the right function that was public all along? > Thousands of people, some of them much smarter than > you or I, have not only decided that C++ should do this (which could > be a bug) but explained at great length and in great detail why C++ > works this way (thus showing that it is not a bug). Bah. Thousands of people could never be wrong, eh? Anyways, I don't think this is thousands of people being wrong, but just the g++ devs making a small mistake. > You have been given a precise reference to a good example of such an > explanation but you ignore it. Inaccessible. I don't have that book, and it's not in my local library. > This was offtopic anyway. I labelled it as such, so that those who didn't want to read about it could ignore it. > if you still have questions address them to a C++ forum. I've done that, but I thought I could pick the brains of Debian users anyways. If your brain is not available for picking, then just ignore this thread. - Jordi G. H. -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
|
|
#10 |
|
Messages: n/a
Hébergeur: |
On Thu May 22 2008 10:49:25 Jordi Gutiérrez Hermoso wrote:
> You keep talking about scope. The access specifier should affect scope > and name resolution? This does not make sense! The public function is > available, a using declaration should bring that function from A's > scope into B's scope, but the compiler tries to resolve the call > "b.f(a)" call to the inaccessible private function anyways. No it doesn't. The error message, which you keep failing to post, would be for the line of the "using", indicating that you're attempting to "using" a private function. This is not the same as trying "to resolve the call". You are creating a permanent record of your very uninformed status, and teaching you basic C++ programming is off-topic for this list. Please stop. Go study the issue. If you have questions post them to a C++ list. --Mike Bird -- To UNSUBSCRIBE, email to debian-user-REQUEST@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org |
|
![]() |
| Outils de la discussion | |
|
|