Topic: Q. Class member access


Author: wmm@fastdial.net
Date: 2000/08/25
Raw View
In article <t0tpumxsdbt.fsf@pdss7.trc.rwcp.or.jp>,
  Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote:
> >         struct X {
> >             static int i;
> >         };
> >         void f(X* p) {
> >             p->::X::i = 3;
> >         }
> >
> >         namespace N {
> >             typedef int I;
> >         }
> >         void g(int* p) {
> >             p->::N::~I();
> >         }
> But I now have another question curiously.
>
> If the above is right, is the below is right?
>
>   struct A { };
>   struct B {
>       static void f();
>   };
>
>   void g() {
>       A a;
>       a.::B::f();
>   }
>
> If it is not OK, what sort of difference between them?

What is different is that B::f() is not a member of class A,
which is the class of the object expression.  (5.2.5p2 requires
that the id-expression be a member of the class of the object
expression or one of its base classes; there's no exception
made for static members.)

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 2000/08/25
Raw View
wmm@fastdial.net writes:
> > How about the following example?
> >
> >   namespace M {
> >     template <class T> struct B {
> >          void f();
> >     };
> >
> >     struct D: B<int> { };
> >   }
> >
> >   void g() {
> >     M::D d;
> >     d.B<int>::f();   // Is this right?
> >   }
> >
> > [snip]
>
> I'm not sure why you think this might be ill-formed.  If you
> go step-by-step through 3.4.5p1, it comes out right:
Thank you for responding my question.

> 1) "The identifier is first looked up in the class of the object
> expression."  It's found there as the template "B" because of
> class name injection.  (There's actually an issue on the core
> language issues list about exactly how class name injection
> works for class templates, but I think it's pretty clear that
> it has to work in such a way that the injected name can be used
> either as a template name or a class name.)
I did not know the specifiction of class name injection. I got it now.
The above example, both template name "B" and class name "B" are intoroduced
to the scope of class D.
I learned that

   d.B<int>::f();

is equivalent to

   d.B::f();

M. Morita

---
[ 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: wmm@fastdial.net
Date: 2000/08/22
Raw View
In article <t0tu2cq8yu7.fsf@pdss7.trc.rwcp.or.jp>,
  Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote:
> I have some more questions.
>
> 3.4.5.p2 says
>  ... If the type of the object expression is of pointer to scalar
> type, the unqualified-id is looked up in the context of the complete
> postfix-expression.
>
> Here, what sort of case does the above mention?
> I can not imagine that case.

Here's an example:

        typedef int I;
        int* p;
        void f() {
            p->~I();
        }

"I" is looked up in the context of the expression.  (I believe
this is the only valid case for this rule; the fact that it
appears in both paragraphs 2 and 3 is just an accident of the
fact that class destructors have additional constraints beyond
those of other unqualified-ids, so p2 applies to all
unqualified-ids and p3 applies to destructor-like
unqualified-ids only.)

> Sorry, I have one more question.
> 3.4.5p5 says
> If the qualified-id has the form
>
>   ::class-name-or-namespace-name:: ...
>
> the class-name-or-namespace-name is looked up in global scope as a
> class-name or namespace-name.
>
> I can not imagine such a case.

Here are a couple, one for a class, one for a namespace:

        struct X {
            static int i;
        };
        void f(X* p) {
            p->::X::i = 3;
        }

        namespace N {
            typedef int I;
        }
        void g(int* p) {
            p->::N::~I();
        }

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: wmm@fastdial.net
Date: 2000/08/22
Raw View
In article <t0tg0o2llpe.fsf@pdss7.trc.rwcp.or.jp>,
  Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote:
> How about the following example?
>
>   namespace M {
>     template <class T> struct B {
>          void f();
>     };
>
>     struct D: B<int> { };
>   }
>
>   void g() {
>     M::D d;
>     d.B<int>::f();   // Is this right?
>   }
>
> The standard says that it is looked up in the context of the entire
> postfix-expression and shall name a class or function template.
> The lookup failed "B" is a template name in the above case.
> So, it is ill-formed? (IMO, it is right)

I'm not sure why you think this might be ill-formed.  If you
go step-by-step through 3.4.5p1, it comes out right:

1) "The identifier is first looked up in the class of the object
expression."  It's found there as the template "B" because of
class name injection.  (There's actually an issue on the core
language issues list about exactly how class name injection
works for class templates, but I think it's pretty clear that
it has to work in such a way that the injected name can be used
either as a template name or a class name.)

2) "If the identifier is not found..."  It was found, so skip
this.

3) "If the lookup in the class of the object expression finds
a template, the name is also looked up in the context of the
entire postfix-expression..."  The in-class lookup did find a
template (the "B" that was injected into class template "B");
the lookup in the context of the postfix-expression does not
find "B" (it's inside the namespace "M").

4) "if the name is not found, the name found in the class of
the object expressioni is used..."  This one is satisfied, so
the injected name "B" is used, with no problems.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 2000/08/25
Raw View
wmm@fastdial.net writes:
> In article <t0tu2cq8yu7.fsf@pdss7.trc.rwcp.or.jp>,
>   Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote:
> > I have some more questions.
> >
> > 3.4.5.p2 says
> >  ... If the type of the object expression is of pointer to scalar
> > type, the unqualified-id is looked up in the context of the complete
> > postfix-expression.
> >
> > Here, what sort of case does the above mention?
> > I can not imagine that case.
>
> Here's an example:
>
>         void f() {
>             p->~I();
>         }
Thank you for replying.

> > 3.4.5p5 says
> > If the qualified-id has the form
> >
> >   ::class-name-or-namespace-name:: ...
> >
> > the class-name-or-namespace-name is looked up in global scope as a
> > class-name or namespace-name.
> >
> > I can not imagine such a case.
>
> Here are a couple, one for a class, one for a namespace:
>
>         struct X {
>             static int i;
>         };
>         void f(X* p) {
>             p->::X::i = 3;
>         }
>
>         namespace N {
>             typedef int I;
>         }
>         void g(int* p) {
>             p->::N::~I();
>         }
But I now have another question curiously.

If the above is right, is the below is right?

  struct A { };
  struct B {
      static void f();
  };

  void g() {
      A a;
      a.::B::f();
  }

If it is not OK, what sort of difference between them?

Thank you in advance.

M. Morita

---
[ 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: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 2000/08/18
Raw View
Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> writes:
> wmm@fastdial.net writes:
> > > I have a question about 3.4.5 Class member access p1.
> > >
> > > ... The identifier is first looked up in the class of the object
> > expression.
> > > If the identifier is not found, it is looked up in the context of the
> > entire
> > > postfix-expression and shall name a class or function template.
> > >
> > The case where this would normally come up is something like
> > the following:
> >
> >     template <class T> struct B {
> >         void f();
> >     };
> >
> >     struct D: B<int> { };
> >
> >     void g() {
> >         D d;
> >         d.B<int>::f();
> >     }
> >
> > You have to know whether "B" is a template name or not in
> > order to determine whether the "<" is part of a template-id
> > (as it is in this case) or a less-than operator, so you have
> > to look up "B".
> Thank you for a good example. I understood that it is said for
> the only case that identifier is a template name.
Here, another thought comes across to me.
How about the following example?

  namespace M {
    template <class T> struct B {
         void f();
    };

    struct D: B<int> { };
  }

  void g() {
    M::D d;
    d.B<int>::f();   // Is this right?
  }

The standard says that it is looked up in the context of the entire
postfix-expression and shall name a class or function template.
The lookup failed "B" is a template name in the above case.
So, it is ill-formed? (IMO, it is right)

> I have some more questions.
> [snip]
>
> 3.4.5p5 says
> If the qualified-id has the form
>
>   ::class-name-or-namespace-name:: ...
>
> the class-name-or-namespace-name is looked up in global scope as a
> class-name or namespace-name.
>
> I can not imagine such a case.
>   class A { ... };
>
>   void foo() {
>      A a;
>      a.::xxx;  // what sort of case as actual usages?
>   }
>
For this question, my colleague showed me the following example:

  struct A {
    void foo();  // I wish to call
  };

  namespace N {
    struct A : ::A {
      void foo();
    };
    struct D : A {
    };
  }

  void bar() {
    N::D a;
    a.::A::foo();
  }

I learned this syntax has meaning in some cases.

Thank you in advance.

M. Morita

---
[ 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: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 2000/08/11
Raw View
Hi,
I have a question about 3.4.5 Class member access p1.

... The identifier is first looked up in the class of the object expression.
If the identifier is not found, it is looked up in the context of the entire
postfix-expression and shall name a class or function template.

Here, the latter case which means that if the identifier is not found
in the class scope, the ordinary lookup will work in the position of
postfix-expression?
For example,

  class A {
     int member;
  };

  A a;

  void foo() {
     a.member = 1;   // (a)
     a.xxx = 2;      // (b)
  }

I think (a) is the first case. (b) is the latter case.
xxx is looked up the function block scope of foo and more over global scope.
Is that right? (am i missing something?)

If there is a practical usage, please show me a example.

Thanks in advance.

M. Morita

---
[ 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: wmm@fastdial.net
Date: 2000/08/11
Raw View
In article <t0tvgx81348.fsf@pdss7.trc.rwcp.or.jp>,
  Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote:
> Hi,
> I have a question about 3.4.5 Class member access p1.
>
> ... The identifier is first looked up in the class of the object
expression.
> If the identifier is not found, it is looked up in the context of the
entire
> postfix-expression and shall name a class or function template.
>
> Here, the latter case which means that if the identifier is not found
> in the class scope, the ordinary lookup will work in the position of
> postfix-expression?
> For example,
>
>   class A {
>      int member;
>   };
>
>   A a;
>
>   void foo() {
>      a.member = 1;   // (a)
>      a.xxx = 2;      // (b)
>   }
>
> I think (a) is the first case. (b) is the latter case.
> xxx is looked up the function block scope of foo and more over global
scope.
> Is that right? (am i missing something?)

This is one of the more obscure passages in the Standard,
I think.  It's not dealing with what you think it is.
Read the first sentence carefully -- 3.4.5p1 deals specifically
with the case where the identifier after . or -> is followed
by a "<".  The lookup rules in 3.4.5p1 say how a compiler can
determine whether that "<" is a less-than operator or part of
a template-id.

The case where this would normally come up is something like
the following:

    template <class T> struct B {
        void f();
    };

    struct D: B<int> { };

    void g() {
        D d;
        d.B<int>::f();
    }

You have to know whether "B" is a template name or not in
order to determine whether the "<" is part of a template-id
(as it is in this case) or a less-than operator, so you have
to look up "B".

I believe this paragraph predates the addition of class name
injection, which is why you have this stuff about finding
it in the class versus finding it in the context of the
expression; I think it should have been revised when class
name injection was added to the language but was overlooked.
There are already issues regarding class name injection for
class templates and on this particular paragraph (why it
talks about function templates at all is a mystery), so
I'll add some verbiage to those issues in the Core Language
issues list about possibly revising this paragraph.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ 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: Masao Morita <m-morita@pdss7.trc.rwcp.or.jp>
Date: 2000/08/13
Raw View
wmm@fastdial.net writes:
> In article <t0tvgx81348.fsf@pdss7.trc.rwcp.or.jp>,
>   Masao Morita <m-morita@pdss7.trc.rwcp.or.jp> wrote:
> > Hi,
> > I have a question about 3.4.5 Class member access p1.
> >
> > ... The identifier is first looked up in the class of the object
> expression.
> > If the identifier is not found, it is looked up in the context of the
> entire
> > postfix-expression and shall name a class or function template.
> >
> > Here, the latter case which means that if the identifier is not found
> > in the class scope, the ordinary lookup will work in the position of
> > postfix-expression?
> > [snip]
>
> The case where this would normally come up is something like
> the following:
>
>     template <class T> struct B {
>         void f();
>     };
>
>     struct D: B<int> { };
>
>     void g() {
>         D d;
>         d.B<int>::f();
>     }
>
> You have to know whether "B" is a template name or not in
> order to determine whether the "<" is part of a template-id
> (as it is in this case) or a less-than operator, so you have
> to look up "B".
Thank you for a good example. I understood that it is said for
the only case that identifier is a template name.
Though, there are some difficulties to understand for me.
I have some more questions.

3.4.5.p2 says
 ... If the type of the object expression is of pointer to scalar
type, the unqualified-id is looked up in the context of the complete
postfix-expression.

Here, what sort of case does the above mention?
I can not imagine that case.

  int *i;

  void foo() {
    i->xxx = 1;  // incredible ???
  }

Sorry, I have one more question.
3.4.5p5 says
If the qualified-id has the form

  ::class-name-or-namespace-name:: ...

the class-name-or-namespace-name is looked up in global scope as a
class-name or namespace-name.

I can not imagine such a case.
  class A { ... };

  void foo() {
     A a;
     a.::xxx;  // what sort of case as actual usages?
  }

Thank you in advance.

M. Morita

---
[ 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              ]