Topic: Behaviour of `using base::member;
Author: Martin von Loewis <loewis@informatik.hu-berlin.de>
Date: 1998/09/24 Raw View
"Alfred Kellner" <alfkellner@magnet.at> writes:
> My (outdated) copy of 7.3.3 [namespace.udecl]/14 is:
> "All instances of the name mentioned in a using-declaration shall be
> accessible. In particular, if a derived class uses a using-declaration
> to access a member of a base class, the member name shall be accessible.
> If the name is that of an overloaded member function, then all functions
> named shall be accessible."
Just for completeness, the FDIS has the additional sentence
>> The base class members mentioned by a using-declaration shall
>> be visible in the scope of at least one of the direct base classes
>> of the class where the using-declaration is specified.
This talks about the well-formedness of the using-declaration only,
not about what it means.
> I think the Note is trying to tell us:
> We can't resolve _overloaded_ functions by inserting
> a using declaration.
No. [class.member.lookup]/4 says
>> If the name of an overloaded function is unambiguously found,
>> overloading resolution (13.3) also takes place before access
>> control. Ambiguities can often be resolved by qualifying a name
>> with its class name.
It clearly assumes that there are ambiguities prior to overload
resolution, and that these ambiguities are to be resolved by
qualifying (although I can't appreciate the normative character of the
second sentence).
They don't have exactly the case we are talking about as an example,
but I still hink that it is ill-formed.
Martin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jason Merrill <jason@cygnus.com>
Date: 1998/09/24 Raw View
>>>>> Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> writes:
> Is the code below legal?
> I use the using directive to remove the ambiguousity
> in a class (D12) with multiple base classes (D1, D2).
> The egcs-1.1 doesn't compile this sample.
egcs 1.1 does not handle class using-directives properly; it treats
them as ARM access declarations.
Jason
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de>
Date: 1998/09/19 Raw View
Is the code below legal?
I use the using directive to remove the ambiguousity
in a class (D12) with multiple base classes (D1, D2).
The egcs-1.1 doesn't compile this sample.
main.cc: In function `int main(int, char **)':
main.cc:34: request for method `clone' is ambiguous
main.cc:35: request for member `x' is ambiguous
class B {
public:
virtual B* clone() const = 0;
};
class D1 : public B {
public:
virtual D1* clone() const {return 0;}
int x;
};
class D2 : public B {
public:
virtual D2* clone() const {return 0;}
int x;
};
class D12 : public D1, public D2 {
public:
using D1::clone;
using D2::x;
};
int main(int argc, char** argv)
{
D12 d;
d.clone(); // line 34
d.x = 0;
}
Ryszard Kabatek
--
Martin-Luther University Halle-Wittenberg
Department of Physical Chemistry
Geusaer Str. 88, 06217 Merseburg, Germany
Tel. +49 3461 46 2487 Fax. +49 3461 46 2129
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Alfred Kellner" <alfkellner@magnet.at>
Date: 1998/09/19 Raw View
Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> wrote
> Is the code below legal?
Yes.
> I use the using directive to remove the ambiguousity
> in a class (D12) with multiple base classes (D1, D2).
>
> The egcs-1.1 doesn't compile this sample.
>
> main.cc: In function `int main(int, char **)':
> main.cc:34: request for method `clone' is ambiguous
> main.cc:35: request for member `x' is ambiguous
>
> class B {
> public:
> virtual B* clone() const = 0;
> };
> class D1 : public B {
> public:
> virtual D1* clone() const {return 0;}
> int x;
> };
> class D2 : public B {
> public:
> virtual D2* clone() const {return 0;}
> int x;
> };
> class D12 : public D1, public D2 {
> public:
> using D1::clone;
> using D2::x;
> };
> int main(int argc, char** argv)
> {
> D12 d;
> d.clone(); // line 34
> d.x = 0;
> }
Usually the purpose of the clone-method is a virtual (copy?) constructor.
Therefore clone() should be implemented in the most derived class.
Doing so, the ambiguity disappears.
What not disappears is the ambiguity when casting to the base (D1::B
or D2::B).
The question arises, wheather to make B a virtual base (if possible).
When
> using D1::clone;
cloning a D12 would generate a D1 - I doubt this is what you want.
class B {
public:
virtual ~B() {};
virtual B* clone() const = 0;
};
class D1 : public /*virtual ?*/ B {
int x;
public:
virtual B* clone() const { return new D1( *this ); }
};
class D2 : public /*virtual ?*/ B {
int x;
public:
virtual B* clone() const { return new D2( *this ); }
};
class D12 : public D1, public D2 {
public:
virtual B* clone() const { return (D2*) new D12( *this ); }
};
void foo( B * pb ) {
B * pB = pb->clone();
D12 * p12 = dynamic_cast<D12*>(pB);
if ( p12 ){
// hey, it's a D12
}
delete pB; // using virtual dtor
}
int main (){
D12 d;
foo( (D2*) &d );
}
--ALfred
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: loewis@informatik.hu-berlin.de (Martin von Loewis)
Date: 1998/09/21 Raw View
In article <01bde40e$6f496d00$15dcdcdc@mentor.magnet.at>,
Alfred Kellner <alfkellner@magnet.at> wrote:
>
>Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> wrote
>
>> Is the code below legal?
>
>Yes.
Then what exactly is the note in 7.3.3/14 telling us?
Martin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: loewis@informatik.hu-berlin.de (Martin von Loewis)
Date: 1998/09/21 Raw View
In article <36039FF3.FE37BF1B@rumcajs.chemie.uni-halle.de>,
Ryszard Kabatek <kabatek@chemie.uni-halle.de> wrote:
>Is the code below legal?
>I use the using directive to remove the ambiguousity
>in a class (D12) with multiple base classes (D1, D2).
This technique is explicitly out-ruled in the standard.
7.3.3 [namespace.udecl]/14 has the following Note
>> [Note: because a using declaration des ignates a base class member
>> (and not a member subobject or a member function of a base class
>> subobject), a using declaration cannot be used to resolve inherited
>> member ambiguities.
I have to say that I understand neither the reasoning nor the example.
Why isn't B::x hidden by D::x? And why wouldn't lookup stop as soon
as a using-declaration is encountered?
Martin
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1998/09/21 Raw View
Ryszard Kabatek <rysio@rumcajs.chemie.uni-halle.de> writes:
> The egcs-1.1 doesn't compile this sample.
> main.cc: In function `int main(int, char **)':
> main.cc:34: request for method `clone' is ambiguous
> main.cc:35: request for member `x' is ambiguous
Yup, known bug. using declarations within classes are not completely
supported yet. :-(
--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
http://www.dcc.unicamp.br/~oliva
Universidade Estadual de Campinas, SP, Brasil
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Alfred Kellner" <alfkellner@magnet.at>
Date: 1998/09/22 Raw View
Martin von Loewis wrote:
>
> In article <36039FF3.FE37BF1B@rumcajs.chemie.uni-halle.de>,
> Ryszard Kabatek <kabatek@chemie.uni-halle.de> wrote:
> >Is the code below legal?
> Alfred Kellner <alfkellner@magnet.at> wrote:
> >Yes.
Martin von Loewis wrote:
>
> Then what exactly is the note in 7.3.3/14 telling us?
[....]
> This technique is explicitly out-ruled in the standard.
> 7.3.3 [namespace.udecl]/14 has the following Note
>
> >> [Note: because a using declaration des ignates a base class member
> >> (and not a member subobject or a member function of a base class
> >> subobject), a using declaration cannot be used to resolve inherited
> >> member ambiguities.
>
> I have to say that I understand neither the reasoning nor the example.
> Why isn't B::x hidden by D::x? And why wouldn't lookup stop as soon
> as a using-declaration is encountered?
>
> Martin
My (outdated) copy of 7.3.3 [namespace.udecl]/14 is:
"All instances of the name mentioned in a using-declaration shall be
accessible. In particular, if a derived class uses a using-declaration
to access a member of a base class, the member name shall be accessible.
If the name is that of an overloaded member function, then all functions
named shall be accessible."
with no Note attached.
However, since 7.3.3/14 is IMO about overloaded members (with all their
ambiguitiy-implications).
I belive this Note talks about resolution of overloaded (function-) names
within a single scope, and not about name lookup from different scopes,
which is the case with multiple inheritance (as in Ryszard's sample).
I think the Note is trying to tell us:
We can't resolve _overloaded_ functions by inserting
a using declaration.
<sample>
class B {
public:
void f(char); // *)
void f(unsigned char); // **)
};
class A {
public:
void f(double); // ***)
};
class D: public A, public B {
public:
// void bar() { B::f( 1 ); }
// ambiguous between *) and **)
// and ? using B::f ; does not help, so we do
void bar() { B::f( char(1) ); }
using A::f ; // *) and **) not considered
void foo() { f(1); } // calls A::f(double)
};
</sample>
--ALfred
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]