Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Re: visibility of typedefs

Reply
Thread Tools

Re: visibility of typedefs

 
 
Alexander Stippler
Guest
Posts: n/a
 
      06-24-2003
tom_usenet wrote:

>
> Move the above line above your operator() and Comeau seems happy.
> Looks like a compiler bug.
>
> e.g. this worked:
>
>
> template <typename D>
> class ConstMatrix
> {
> public:
> typedef typename D::Index Index;
>
> double
> operator()(const Index &i) const { return 0.0; }
> };
>
> template <typename D>
> class Matrix
> : public ConstMatrix<D>
> {
> public:
> typedef typename D::Index Index;
>
> using ConstMatrix<D>:perator();
>
> double
> operator()(const Index &i);
> };
>
> template <typename D>
> double
> Matrix<D>:perator()(const Index &i) { return 0.0; }
>
> class X
> {
> public:
> typedef int Index;
> };
>
> int
> main()
> {
> Matrix<X> m;
> m(3);
> }
>
> Tom


But should this "solution" not hide Matrix<D>:perator(), since it is
declared after the using? According to the standard, not to como!

Alex
 
Reply With Quote
 
 
 
 
tom_usenet
Guest
Posts: n/a
 
      06-24-2003
On Tue, 24 Jun 2003 11:44:10 +0200, Alexander Stippler
<(E-Mail Removed)-ulm.de> wrote:

>tom_usenet wrote:
>
>>
>> Move the above line above your operator() and Comeau seems happy.
>> Looks like a compiler bug.
>>
>> e.g. this worked:
>>
>>
>> template <typename D>
>> class ConstMatrix
>> {
>> public:
>> typedef typename D::Index Index;
>>
>> double
>> operator()(const Index &i) const { return 0.0; }
>> };
>>
>> template <typename D>
>> class Matrix
>> : public ConstMatrix<D>
>> {
>> public:
>> typedef typename D::Index Index;
>>
>> using ConstMatrix<D>:perator();
>>
>> double
>> operator()(const Index &i);
>> };
>>
>> template <typename D>
>> double
>> Matrix<D>:perator()(const Index &i) { return 0.0; }
>>
>> class X
>> {
>> public:
>> typedef int Index;
>> };
>>
>> int
>> main()
>> {
>> Matrix<X> m;
>> m(3);
>> }
>>
>> Tom

>
>But should this "solution" not hide Matrix<D>:perator(), since it is
>declared after the using? According to the standard, not to como!


Where in the standard? using declarations never hide members, only add
them to the scope of the derived class. Where you put a using
declaration in the class should make no difference AFAIK.

Tom
 
Reply With Quote
 
 
 
 
Alexander Stippler
Guest
Posts: n/a
 
      06-24-2003
Hello,

>>But should this "solution" not hide Matrix<D>:perator(), since it is
>>declared after the using? According to the standard, not to como!

>
> Where in the standard? using declarations never hide members, only add
> them to the scope of the derived class. Where you put a using
> declaration in the class should make no difference AFAIK.
>
> Tom


In my understanding of the standard, the position of a using declaration is
quite relevant. The section of the standard, I refer to, is 7.3.3 (The
using declaration, 9):

The entity declared by a using-declaration shall be known in the context
using it according to its definition at the point of the using-declararion.
Definitions added to the namespace after the using-declaration are not
considered when a use of the name is made. [Example:

namespace a {
void f(int);
}

using A::f; // f is a synonym for A::f;
// that is, for A::f(int).

namespace A {
void f(char);
}

void foo()
{
f('a'); // calls f(int),
// even though f(char) exists.
}

void bar()
{
using A::f; // f is a synonym for A::f;
// that is, for A::f(int) and A::f(char).
f('a'); // calls f(char)
}
-- end example]

IMO that means for my particular example, that the using-declaration has to
placed after the declaration of the data()-method in the derived class, not
above it, like

class A
{
public:
void
data() const;
};

class B
: public A
{
public:
void
data();

using A::data;
};

void dummy(const B &b)
{
b.data();
}
int
main()
{
B b;
dummy(b);
}

Otherwise the code above would be ill-formed IMO. Am I misinterpreting?
What does the section of the standard really mean?

regards,
Alex
 
Reply With Quote
 
tom_usenet
Guest
Posts: n/a
 
      06-24-2003
On Tue, 24 Jun 2003 16:43:12 +0200, Alexander Stippler
<(E-Mail Removed)-ulm.de> wrote:

>In my understanding of the standard, the position of a using declaration is
>quite relevant. The section of the standard, I refer to, is 7.3.3 (The
>using declaration, 9):


Right, 7.3.3 is where I've been looking too, but the observation that
position is unimportant came from experience...

>
>The entity declared by a using-declaration shall be known in the context
>using it according to its definition at the point of the using-declararion.
>Definitions added to the namespace after the using-declaration are not
>considered when a use of the name is made. [Example:
>
> namespace a {
> void f(int);
> }
>
> using A::f; // f is a synonym for A::f;
> // that is, for A::f(int).
>
> namespace A {
> void f(char);
> }
>
> void foo()
> {
> f('a'); // calls f(int),
> // even though f(char) exists.
> }
>
> void bar()
> {
> using A::f; // f is a synonym for A::f;
> // that is, for A::f(int) and A::f(char).
> f('a'); // calls f(char)
> }
>-- end example]


Right, so with a using declaration you are only referring to something
you've already declared, not to any later overloads of the same
function.

>
>IMO that means for my particular example, that the using-declaration has to
>placed after the declaration of the data()-method in the derived class, not
>above it, like
>
>class A
>{
> public:
> void
> data() const;


Here we've declared A::data.

>};
>
>class B
> : public A
>{


Here, A::data has already been declared.

> public:
> void
> data();
>
> using A::data;


Also here, A::data has already been declared. B::data is of no
relevence, since it is a different name to A::data.

>};
>
>void dummy(const B &b)
>{
> b.data();
>}
>int
>main()
>{
> B b;
> dummy(b);
>}
>
>Otherwise the code above would be ill-formed IMO. Am I misinterpreting?


Yup, I'm pretty sure you are.

>What does the section of the standard really mean?


Just that a using declaration only refers to versions of a name that
have already been declared, not those that are yet to be declared. As
a result, that paragraph only applies to namespace scope names, since
you can't reopen class definitions.

The relevent bit regarding derived classes, etc. is 7.3.3/12 and /13.

Tom
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-24-2003
"tom_usenet" <(E-Mail Removed)> wrote...
> On Tue, 24 Jun 2003 16:43:12 +0200, Alexander Stippler
> <(E-Mail Removed)-ulm.de> wrote:
>
> >In my understanding of the standard, the position of a using declaration

is
> >quite relevant. The section of the standard, I refer to, is 7.3.3 (The
> >using declaration, 9):

>
> Right, 7.3.3 is where I've been looking too, but the observation that
> position is unimportant came from experience...
>
> >
> >The entity declared by a using-declaration shall be known in the context
> >using it according to its definition at the point of the

using-declararion.
> >Definitions added to the namespace after the using-declaration are not
> >considered when a use of the name is made. [Example:
> >
> > namespace a {
> > void f(int);
> > }
> >
> > using A::f; // f is a synonym for A::f;
> > // that is, for A::f(int).
> >
> > namespace A {
> > void f(char);
> > }
> >
> > void foo()
> > {
> > f('a'); // calls f(int),
> > // even though f(char) exists.
> > }
> >
> > void bar()
> > {
> > using A::f; // f is a synonym for A::f;
> > // that is, for A::f(int) and A::f(char).
> > f('a'); // calls f(char)
> > }
> >-- end example]

>
> Right, so with a using declaration you are only referring to something
> you've already declared, not to any later overloads of the same
> function.
>
> >
> >IMO that means for my particular example, that the using-declaration has

to
> >placed after the declaration of the data()-method in the derived class,

not
> >above it, like
> >
> >class A
> >{
> > public:
> > void
> > data() const;

>
> Here we've declared A::data.
>
> >};
> >
> >class B
> > : public A
> >{

>
> Here, A::data has already been declared.
>
> > public:
> > void
> > data();


BAM!!!! Here A::data has been HIDDEN! Are you forgetting it
or something?

> >
> > using A::data;

>
> Also here, A::data has already been declared. B::data is of no
> relevence, since it is a different name to A::data.


It's NOT a different name, it is specifically the same name. For
the purposes of name hiding only unqualified names are considered.

And the 'using' statement here _redeclares_ A::data in current
scope, brings it back from the shadows, so to speak.

>
> >};
> >
> >void dummy(const B &b)
> >{
> > b.data();
> >}
> >int
> >main()
> >{
> > B b;
> > dummy(b);
> >}
> >
> >Otherwise the code above would be ill-formed IMO. Am I misinterpreting?

>
> Yup, I'm pretty sure you are.


I'm pretty sure you are.

>
> >What does the section of the standard really mean?

>
> Just that a using declaration only refers to versions of a name that
> have already been declared, not those that are yet to be declared. As
> a result, that paragraph only applies to namespace scope names, since
> you can't reopen class definitions.
>
> The relevent bit regarding derived classes, etc. is 7.3.3/12 and /13.


???

Victor


 
Reply With Quote
 
tom_usenet
Guest
Posts: n/a
 
      06-25-2003
On Tue, 24 Jun 2003 11:12:25 -0400, "Victor Bazarov"
<(E-Mail Removed)> wrote:

>> Here, A::data has already been declared.
>>
>> > public:
>> > void
>> > data();

>
>BAM!!!! Here A::data has been HIDDEN! Are you forgetting it
>or something?


Apologies if I wasn't clear, but although A::data is hidden by
B::data, an explicit call to A::data is still fine, since A::data has
been declared.

>
>> >
>> > using A::data;

>>
>> Also here, A::data has already been declared. B::data is of no
>> relevence, since it is a different name to A::data.

>
>It's NOT a different name, it is specifically the same name. For
>the purposes of name hiding only unqualified names are considered.
>
>And the 'using' statement here _redeclares_ A::data in current
>scope, brings it back from the shadows, so to speak.


Right, but the point I was making is that it doesn't matter where you
put the using declaration, since A::data is accessible throughout the
declarative scope of B, not just after B::data has been declared, and
adding A::data to the declarative scope of B can be done before
B::data or after, in the same way that it doesn't matter which order
you declare member functions in. Later member function declarations in
the same class with the same name won't hide earlier ones, but
overload them.

>> Just that a using declaration only refers to versions of a name that
>> have already been declared, not those that are yet to be declared. As
>> a result, that paragraph only applies to namespace scope names, since
>> you can't reopen class definitions.
>>
>> The relevent bit regarding derived classes, etc. is 7.3.3/12 and /13.

>
>???


Is the reference not clear?

Tom
 
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
circular dependencies and typedefs Dylan C++ 7 07-07-2004 06:59 PM
too many typedefs cppaddict C++ 2 06-19-2004 04:07 AM
using declarations with nested typedefs Dave C++ 4 12-05-2003 11:45 PM
Templates and Typedefs dwrayment C++ 6 08-14-2003 05:52 AM
STL typedefs and base class pointer problem emerth C++ 3 08-08-2003 05:47 AM



Advertisments