|  | Using declaration |  | |
| | | Guest |  |
| Posted: Thu Aug 07, 2008 11:08 am Post subject: Using declaration |  |
| |  | |
Hi,
In the code below, as I understand, the using declaration injects the base class B's members with name 'f' in the scope of the derived class.This means that in scope of D, we have two functions named 'f' as follows:
void f(D* this, int); void f(B* this, int);
I convinced myself that the call d.f(2) calls D::f because the call is internally translated as "d.f(&d, int)" as this is a better match without requiring any conversion.
However I got confused when I read $7.3.3/16 (N2691) "For the purpose of overload resolution, the functions which are introduced by a using- declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function, and in all other respects the function remains a member of the base class."
This means that for the purpose of making the function call d.f(2), the candidate functions are
void f(D* this, int); // D::f void f(D* this, int); // As per $7.3.3/16 void f(B* this, int) is interpreted as void f(D* this, int)
This in my opinion is an ambiguous function call. So now my question is, that why does the call d.f(2) gets routed to D::f?
struct B { void f(int){ } void f(){ } };
struct D : B { using B::f; void f(int){} };
int main(){ D d; d.f(2); }
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Alberto Ganesh Barbati |  |
| Posted: Thu Aug 07, 2008 3:58 pm Post subject: Re: Using declaration |  |
| |  | |
rkldabs@gmail.com ha scritto:
| Quote: | Hi,
In the code below, as I understand, the using declaration injects the base class B's members with name 'f' in the scope of the derived class.This means that in scope of D, we have two functions named 'f' as follows:
void f(D* this, int); void f(B* this, int);
|
Nonono. A member function is *not* a function with a hidden "this" parameter, although it might be implemented at low-level as such. In particular the "this" parameter has a special treatment in what regards overloading.
| Quote: | I convinced myself that the call d.f(2) calls D::f because the call is internally translated as "d.f(&d, int)" as this is a better match without requiring any conversion.
|
Who said that d.f(2) is internally translated as d.f(&d, 2)??? That is not written in the standard and it's not happening.
d.f(2) effectively looks f in the scope of D (D being the static type of d). In your example, this will end up calling D::f(int).
| Quote: | However I got confused when I read $7.3.3/16 (N2691) "For the purpose of overload resolution, the functions which are introduced by a using- declaration into a derived class will be treated as though they were members of the derived class. In particular, the implicit this parameter shall be treated as if it were a pointer to the derived class rather than to the base class. This has no effect on the type of the function, and in all other respects the function remains a member of the base class."
This means that for the purpose of making the function call d.f(2), the candidate functions are
void f(D* this, int); // D::f void f(D* this, int); // As per $7.3.3/16 void f(B* this, int) is interpreted as void f(D* this, int)
This in my opinion is an ambiguous function call. So now my question is, that why does the call d.f(2) gets routed to D::f?
|
The call is not ambiguous because of 7.3.3/12 (/15 in the draft for C++0x):
"When a using-declaration brings names from a base class into a derived class scope, member functions in the derived class override and/or hide member functions with the same name and parameter types in a base class (rather than conflicting)."
Summarizing:
1) the using declaration introduced B::f() and B::f(int) in the scope of D 2) the declaration of D::f(int) hides and effectively replaces B::f(int) which is no longer visible in the scope of D.
the result is that, in the scope of D, you have only two functions: D::f() which is an alias for B::f() and D::f(int).
HTH,
Ganesh
| Quote: | struct B { void f(int){ } void f(){ } };
struct D : B { using B::f; void f(int){} };
int main(){ D d; d.f(2); }
|
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
| | | Guest |  |
| Posted: Thu Aug 21, 2008 1:28 pm Post subject: Re: Using declaration |  |
On Aug 7, 7:08 am, rkld...@gmail.com wrote:
#include <iostream>
struct base1 { void function() { std::cout << "base1\n"; } };
struct base2 { void function() { std::cout << "base2\n"; } };
struct derived : base1, base2 { using base1::function; };
int main() { derived instance; instance.function(); }
In the definition of 'derived', 'base1::function' becomes 'derived::function' by rule, and when resolving the overloaded function 'function' in 'instance.function();', 'instance' is considered 'derived' vice any other type, dissolving any ambiguity in the statement. Kevin P. Barry
-- [ See LINK for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |
| |
|
|