![]() |
C++ reluctant to overload function
A very simple question follows.
Is it correct operation that the following fails to compile if I uncomment the line indicated, and if so, what rule precludes overloading the function foo() in the manner I am attempting (based on type/number of operators)? It seems unambiguous to me. Thanks Steve ************************************* #include <cstdio> struct a { // uncommenting the following line causes it to fail to compile // void foo(int x) { std::printf("%d\n", 2*x); } void do_foo(); }; namespace { void foo(int x, int y) {std::printf("%d\n", x + y); } } void a::do_foo() { foo(2,4); } main() { a y; y.do_foo(); } |
Re: C++ reluctant to overload function
On 10/12/2010 10:14 AM, Steve Pope wrote:
> A very simple question follows. > > Is it correct operation that the following fails to compile if > I uncomment the line indicated, and if so, what rule precludes > overloading the function foo() in the manner I am attempting > (based on type/number of operators)? > > It seems unambiguous to me. > > Thanks > > Steve > > ************************************* > > > #include<cstdio> > > struct a { > > // uncommenting the following line causes it to fail to compile > // void foo(int x) { std::printf("%d\n", 2*x); } > > void do_foo(); > }; > > namespace { > void foo(int x, int y) {std::printf("%d\n", x + y); } > } > > void a::do_foo() { > foo(2,4); > } > > main() { int main() { // there is no implicit int in C++ > a y; > y.do_foo(); > } The program with uncommented 'foo' member should fail to compile - too many arguments for a::foo. Name lookup when in a member function finds the member 'foo' which actually *hides* any other 'foo', and that's why the '<unnamed namespace>::foo' should NOT be found during that lookup and is *not* considered an overload. What compiler finds the non-member 'foo' if you uncomment 'a::foo'? V -- I do not respond to top-posted replies, please don't ask |
Re: C++ reluctant to overload function
Pete Becker <pete@versatilecoding.com> wrote:
>On 2010-10-12 10:14:20 -0400, Steve Pope said: >> A very simple question follows. >> Is it correct operation that the following fails to compile if >> I uncomment the line indicated, and if so, what rule precludes >> overloading the function foo() in the manner I am attempting >> (based on type/number of operators)? >Overloading only applies to names that are defined in the same scope. >Here, the first version of foo is defined as a member of struct a and >the second version of foo is defined in the anonymous namespace. Two >different scopes, so no overloading. That does appear to be going on. Thanks. Not sure it's a reasonable restriction though. Not that this opinion counts for anything ;-) Steve |
Re: C++ reluctant to overload function
Victor Bazarov <v.bazarov@comcast.invalid> wrote:
>On 10/12/2010 10:14 AM, Steve Pope wrote: >> main() { > >int main() { // there is no implicit int in C++ Thanks >The program with uncommented 'foo' member should fail to compile - too >many arguments for a::foo. Name lookup when in a member function finds >the member 'foo' which actually *hides* any other 'foo', and that's why >the '<unnamed namespace>::foo' should NOT be found during that lookup >and is *not* considered an overload. >What compiler finds the non-member 'foo' if you uncomment 'a::foo'? None. It just seemed to me that, given the wild abandon with which the linker will usually search for a function that matches the prototype, I'm a bit surprised it doesn't find and use this one. Steve |
Re: C++ reluctant to overload function
Victor Bazarov <v.bazarov@comcast.invalid> wrote:
> Name lookup when in a member function finds > the member 'foo' which actually *hides* any other 'foo', and that's why > the '<unnamed namespace>::foo' should NOT be found during that lookup > and is *not* considered an overload. What is the rationale for that? I can't immediately think of a reason or notivation for that. |
Re: C++ reluctant to overload function
Victor Bazarov <v.Abazarov@comAcast.net> wrote:
>On 10/12/2010 12:37 PM, Juha Nieminen wrote: >> What is the rationale for that? I can't immediately think of a reason >> or notivation for that. >Rationale for what, exactly? For the rules of hiding? Names defined in >a closer scope hide names defined in the outer scope. It's an old rule, >that AFAICT existed from the start in C++. For example, > > int main() > { > double d = 3.14159; > { > int d = 42; > { > d = 666; // changes the int d, not the double d > } > } > > // here 'd' is still 3.14159 > } Well it's not exactly analogous. In the above case the name-mangled names clash, in the case I described in my initial post, they do not. Steve |
Re: C++ reluctant to overload function
Victor Bazarov <v.Abazarov@comAcast.net> wrote:
>On 10/12/2010 3:09 PM, Steve Pope wrote: >> Victor Bazarov<v.Abazarov@comAcast.net> wrote: >>> Rationale for what, exactly? For the rules of hiding? Names defined in >>> a closer scope hide names defined in the outer scope. It's an old rule, >>> that AFAICT existed from the start in C++. For example, >>> int main() >>> { >>> double d = 3.14159; >>> { >>> int d = 42; >>> { >>> d = 666; // changes the int d, not the double d >>> } >>> } >>> >>> // here 'd' is still 3.14159 >>> } >> Well it's not exactly analogous. In the above case the name-mangled >> names clash, in the case I described in my initial post, they do not. >Not sure I understand what you mean here. In your example the name is >'foo'. In my example the name is 'd'. Would it make a difference if I >named my variables 'foo'? What's "name-mangled" have to do with name >resolution or with name hiding? And what *is* "name-mangled", anyway? Unless I am missing something: Overloaded function names do not hide each other because their name-mangled names include the argument types. There is no such distinctoin in your variable "d" in your example. It seems in the situation in my first post, something is at work other than a simple need to resolve names. Some matter of language design philosophy that is more subtle than the scope of the names. Steve |
Re: C++ reluctant to overload function
On 13 okt, 00:40, spop...@speedymail.org (Steve Pope) wrote:
> Victor Bazarov *<v.Abaza...@comAcast.net> wrote: > > > > >On 10/12/2010 3:09 PM, Steve Pope wrote: > >> Victor Bazarov<v.Abaza...@comAcast.net> *wrote: > >>> Rationale for what, exactly? *For the rules of hiding? *Names defined in > >>> a closer scope hide names defined in the outer scope. *It's an old rule, > >>> that AFAICT existed from the start in C++. *For example, > >>> * * int main() > >>> * * { > >>> * * * *double d = 3.14159; > >>> * * * *{ > >>> * * * * * int d = 42; > >>> * * * * * { > >>> * * * * * * *d = 666; // changes the int d, not the double d > >>> * * * * * } > >>> * * * *} > > >>> * * * *// here 'd' is still 3.14159 > >>> * * } > >> Well it's not exactly analogous. *In the above case the name-mangled > >> names clash, in the case I described in my initial post, they do not. > >Not sure I understand what you mean here. *In your example the name is > >'foo'. *In my example the name is 'd'. *Would it make a difference if I > >named my variables 'foo'? *What's "name-mangled" have to do with name > >resolution or with name hiding? *And what *is* "name-mangled", anyway? > > Unless I am missing something: > > Overloaded function names do not hide each other because their > name-mangled names include the argument types. Yes you miss. It is not linker who does resolve names. It is in another way around. Linker is stupid. Compiler is smart. Nothing of it is specified by language rules, it is just done that way by most implementations. > There is no such distinctoin in your variable "d" in your example. The d-s of Victor are of different type and if these had external linkage then compiler had to name-mangle them differently to make difference for linker. > It seems in the situation in my first post, something is at work other > than a simple need to resolve names. *Some matter of language design > philosophy that is more subtle than the scope of the names. No. The C++ overload resolving and two-pass argument dependent lookup and template argument deduction is as complex as it can only get for a poor compiler. If it had to mix all the names from all the scopes available without hiding the names in outer scope then that would cause huge amount of ambiguities (compiler just fails to resolve) in already existing code. |
Re: C++ reluctant to overload function
Victor Bazarov <v.Abazarov@comAcast.net> wrote:
>When *hiding* takes place, overloading is not present. That's what I >think you're missing. You can only overload functions in the same >scope. As soon as there is the same name declared in a more enclosed >scope, it *hides* the name from the outer scope. No overloading in that >case. None. Zero. Zilch. Nada. Actually, poking into this I find that one can overload functions across scopes, it just must be done explicitly. So I can fix the example I first gave as follows. Steve ***************************** #include <cstdio> struct a { // uncommenting the following line no longer // causes it to fail to compile void foo(int x) { std::printf("%d\n", 2*x); } void do_foo(); }; namespace { void foo(int x, int y) {std::printf("%d\n", x + y); } } void a::do_foo() { using ::foo; // because of this line foo(2,4); } main() { a y; y.do_foo(); } |
Re: C++ reluctant to overload function
[snipped previous discussion about issue with overloading]
On 13 Okt., Öö Tiib wrote: > The C++ overload resolving and two-pass argument dependent lookup > and template argument deduction is as complex as it can only get for a > poor compiler. I agree that overload resolving and ADL are quite complex. However, I don't see why C++ should be a poor language in that regard. Or do you mean that most compilers are quite bad at error messages when it comes to errors with ADL/overload resolution? I'd value your opinion. Regards, Stuart |
| All times are GMT. The time now is 06:51 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.