Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > C++ reluctant to overload function

Reply
Thread Tools

C++ reluctant to overload function

 
 
Steve Pope
Guest
Posts: n/a
 
      10-12-2010
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:rintf("%d\n", 2*x); }

void do_foo();
};

namespace {
void foo(int x, int y) {std:rintf("%d\n", x + y); }
}

void a::do_foo() {
foo(2,4);
}

main() {
a y;
y.do_foo();
}


 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      10-12-2010
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:rintf("%d\n", 2*x); }
>
> void do_foo();
> };
>
> namespace {
> void foo(int x, int y) {std:rintf("%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
 
Reply With Quote
 
 
 
 
Steve Pope
Guest
Posts: n/a
 
      10-12-2010
Pete Becker <(E-Mail Removed)> 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
 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-12-2010
Victor Bazarov <(E-Mail Removed)> 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
 
Reply With Quote
 
Juha Nieminen
Guest
Posts: n/a
 
      10-12-2010
Victor Bazarov <(E-Mail Removed)> 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.
 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-12-2010
Victor Bazarov <(E-Mail Removed)> 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
 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-12-2010
Victor Bazarov <(E-Mail Removed)> wrote:

>On 10/12/2010 3:09 PM, Steve Pope wrote:


>> Victor Bazarov<(E-Mail Removed)> 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
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      10-12-2010
On 13 okt, 00:40, (E-Mail Removed) (Steve Pope) wrote:
> Victor Bazarov *<(E-Mail Removed)> wrote:
>
>
>
> >On 10/12/2010 3:09 PM, Steve Pope wrote:
> >> Victor Bazarov<(E-Mail Removed)> *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.
 
Reply With Quote
 
Steve Pope
Guest
Posts: n/a
 
      10-13-2010
Victor Bazarov <(E-Mail Removed)> 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:rintf("%d\n", 2*x); }

void do_foo();
};

namespace {
void foo(int x, int y) {std:rintf("%d\n", x + y); }
}

void a::do_foo() {
using ::foo; // because of this line
foo(2,4);
}

main() {
a y;
y.do_foo();
}


 
Reply With Quote
 
Stuart Redmann
Guest
Posts: n/a
 
      10-13-2010
[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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: C++ reluctant to overload function James Kanze C++ 4 10-14-2010 02:12 PM
Examples of using "reluctant" subexpressions in regexps? david.karr@wamu.net Java 4 04-27-2005 07:46 PM
Help simplify complex regexp needing positive lookahead and reluctant quantifers david.karr@wamu.net Java 7 03-25-2005 09:05 PM
function overload (not operator overload) Ying-Chieh Liao Perl Misc 3 10-11-2004 11:24 AM
How use the overload of>> (or<<) of a class in the overload of << and >> of another class? Piotre Ugrumov C++ 3 01-25-2004 08:08 PM



Advertisments