Topic: Just a simple question


Author: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/07/30
Raw View
>> void f(std::list<int>::iterator iter)
>> // this pulls in namespace std
>> // suppose it also pulls in std::list<int>
>> {
>>      value_type integer; // fine!
>>      // value_type ==> std::list<int>::value_type ==> int
>> }

My reasoning is that if "A::B" appears inside a function prototype, then

   if A is a class, then
          the nested typedefs and nested classes
          of class A don't get pulled in

   if A is a namespace, then
          the nested typedefs and nested classes
          of class A do get pulled in


In other words, if A is a class, then I think of "A::B" as "A_B" -- i.e a
new class defined a the global level with a funny name rather than a
nested class.  Tried reading parts of the standard, but it's rather tough.



Now if "list<int>" is treated as a namespace, then "list<int>::value_type"
gets to be in scope.

Similarly, if "Outer" is treated as a namespace, then "Outer::Inter"
gets to be in scope.  This is explained further below.

>> [edited a little]
>> >> struct Outer {
>> >>
>> >>   struct Inter {
>> >>     struct Inner { int i; };
>> >>   };
>> >>
>> >>   struct Other : public Inter::Inner { };
>> >> };
>> >>
>> >> int
>> >> f (Outer::Other *op)
>> >> {
>> >>   op -> Inter::Inner::i = 0;
>> >> }

If "Outer" is treated as a namespace, then Inter gets to be in scope and
you can say "op->Inter::Inner::i=0".

But there is another point of view.  "Outer" is treated as a namespace
only when applied to objects that live in this cope.  Therefore,
     op->Inter::Inner::i; // ok as op lives in the scope of Outer
     Inter::Inner newobject; // not ok



>void f( Outer::Inter::Inner inn1)
>{
>  Inner inn; // Inner not in  scope
>  ...
>  // but i can say
>  inn1.i = 10;
> }
>
>Do you agree ? or am I wrong ?

I agree with this, but I could be wrong!  Furthermore,

   op -> inn1; // ok (obviously)
   op -> Outer::Inter::Inner::inn1; // ok (obviously)
   op -> ::Outer::Inter::Inner::inn1; // ok (obviously)
   op -> Inter::Inner::inn1; // not ok (?)
   op -> Inner::inn1; // not ok (?)




--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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: Norbert Berzen <norbert@dune.gia.rwth-aachen.de>
Date: 1998/07/27
Raw View
Hello,

can someone tell me if the following is well formed c++:


struct Outer {

  struct Inter {

    struct Inner {

      int i;

    };

  };

  struct Other : public Inter::Inner {

 // empty

  };

};

int
f (Outer::Other *op)
{
  op -> Inter::Inner::i = 0;
}


--
Norbert [norbert@dune.gia.rwth-aachen.de  (134.130.159.38)]

N. Berzen, Geod. Inst. der RWTH-Aachen, Templergraben 55, 52056 Aachen
---
[ 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: Kannan Chellappan <chellapk@nmasd.bel.alcatel.be>
Date: 1998/07/29
Raw View
Siemel Naran wrote:

> [edited a little]
> >> struct Outer {
> >>
> >>   struct Inter {
> >>     struct Inner { int i; };
> >>   };
> >>
> >>   struct Other : public Inter::Inner { };
> >>
> >> };
>
> Consider declaring classes out of line as this is good for
> readability.
>
> >> int
> >> f (Outer::Other *op)
> >> {
> >>   op -> Inter::Inner::i = 0;
> >> }
>
> >I dont see any problem. The structure Inner can be accessed only through
> >Inter (as Inner is in the scope of Inter) and the structures Other and Inter
> >are in the same scope (that of Outer).
>
> If "Outer" were a namespace, then since the declaration of the
> function f(...) uses the namespace "Outer", the compiler pulls
> in this namespace.  Then
>      Inter::Inner::i
> refers to
>      Outer::Inter::Inner::i.
>
> But "Outer" is a class, so does it get pulled in?  I don't think so,
> because if it did get pulled in, the code below would compile.
>

Let us consider a very simple example before i try to explain why i think
so...(without going into your example), let us consider this case :

class A{
public:
int fn1();
int fn2();

//some variables
float f;
...
...

};

int main()
{
  A a;
  A *ptr = &a;
  a.fn1();  // statements in main, not in member fns
  ptr->f = 10.5;
  return 0;
}

The above statements are legal. But it can be noted that the function fn1() and
the variable f are in the scope of the class A. It should be possible for me to
explicitly scope resolve it by saying something like
   a.A::fn1() ;
   or
  ptr->A::f = 10.5;
But since Iam accessing it with the concerned object (a) or pointer (ptr) which
are of type A, i have a feeling that the complier does the necessary scope
resolution as A::
or can i put it like this " the object "a" or the pointer "ptr" brings with
itself the scope resolution A:: "


Back to the original problem, Inter and Other are in the scope of the class
Outer. What is being passed is a pointer to an object of type Other (which is in
the scope of Outer).  So i think, the scope resolution Outer:: is done by the
presence of the pointer (op) in this case.
Hence without saying op->Outer::Inter::Inner::i = 10;, i am able to say
op->Inter::Inner::i = 10;

> void f(std::list<int>::iterator iter)
> // this pulls in namespace std
> // suppose it also pulls in std::list<int>
> {
>      value_type integer; // fine!
>      // value_type ==> std::list<int>::value_type ==> int
> }
>

I cannot do something like this

void f( Outer::Inter::Inner inn1)
{
  Inner inn; // Inner not in  scope
  ...
  // but i can say
  inn1.i = 10;
 }

Do you agree ? or am I wrong ?

> So back to the original example, the 'namespace' Outer (which is
> really a class) would only get pulled in function f(...) were
> a member or static function of class Outer, or a member or static
> function of one of the nested classes of class Outer (i.e. a member
> or static of Outer::Inter or Outer::Inter::Inner).
>
> Here's my correction.  Note that in this case, the scope resolution
> is not really necessary.
>
> >f (Outer::Other *op)
> >{
> >    op -> Inter::Inner::i = 0;
>
>      op -> Outer::Inter::Inner::i = 0;
>
> >Did you face any problems ?
>
> The original code as written does not compile on g++ 2.7.2.3.

I got is compiled on HP C++/HP-UX Version A.10.22   :-)

or is the whole stuff compiler dependent ?

>
>
> --
> ----------------------------------
> Siemel B. Naran (sbnaran@uiuc.edu)
> ----------------------------------
> ---
> [ 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              ]
---
[ 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: Norbert Berzen <norbert@dune.gia.rwth-aachen.de>
Date: 1998/07/29
Raw View
Hello again,

Norbert Berzen wrote (quoted text slightly modified/augmented!):

> struct Outer {
>   struct Inter {
>     struct Inner {
>       int i;
>     };
>   };
>
>   struct Other : public Inter::Inner { };
> };
>
> void
> f (Outer::Other *op)
> {
>   op -> i = 0;                        // a)
>   op -> Inner::i = 0;                 // b)
>   op -> Inter::Inner::i = 0;          // c)
>   op -> Outer::Inter::Inner::i = 0;   // d)
>   op -> ::Outer::Inter::Inner::i = 0; // e)
> }

... did some tests under "DEC OSF1 V3.2" using gcc-2.8.1,
tcc-4.1.2 and DEC-cxx-5.1-1 and got the following results:

      gcc-2.8.1 tcc-4.1.2 cxx-5.1-1
      -----------------------------
  a)      +         +        +
  b)      +         +        -
  c)      -         -        -
  d)      +         +        +
  e)      +         +        -

+ := compiles o.k.
- := fails to compile

My opinion is as follows:

a) o.k. no question

b) Don't know. On one hand one could say that after
   seeing `op ->' the current scope for name lookup
   should be `Outer' and in `Outer' there is no
   directly visible `Inner', so it should not compile!

   On the other hand one could say `Other' is derived
   from a base class named `Inner' no matter if it
   is visible right now and the member `i' is correctly
   qualified by the name of the base class where
   it does belong to, so it should compile o.k.!

c) should compile ok since after seeing `op ->'
   the current scope for name lookup should be
   `Outer' and `Inner' should be visible from there
   when qualified by the directly visible `Inter'.
   So member `i' is uniquely and correctly qualified
   by `Other''s base `Inter::Inner'.

d) o.k. no question

e) o.k. no question

My feeling says that either should compile o.k.!

--
Norbert [norbert@dune.gia.rwth-aachen.de  (134.130.159.38)]

N. Berzen, Geod. Inst. der RWTH-Aachen, Templergraben 55, 52056 Aachen
---
[ 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: scott douglass <sdouglass%_%junk@_.arm.com>
Date: 1998/07/29
Raw View
Norbert Berzen wrote:
 >
 > Hello again,
 >
 > Norbert Berzen wrote (quoted text slightly modified/augmented!):
 >
 > > struct Outer {
 > >   struct Inter {
 > >     struct Inner {
 > >       int i;
 > >     };
 > >   };
 > >
 > >   struct Other : public Inter::Inner { };
 > > };
 > >
 > > void
 > > f (Outer::Other *op)
 > > {
 > >   op -> i = 0;                        // a)
 > >   op -> Inner::i = 0;                 // b)
 > >   op -> Inter::Inner::i = 0;          // c)
 > >   op -> Outer::Inter::Inner::i = 0;   // d)
 > >   op -> ::Outer::Inter::Inner::i = 0; // e)
 > > }
 >
 > [...]
 >
 > My opinion is as follows:
 >
 > a) o.k. no question
 >
 > b) Don't know. On one hand one could say that after
 >    seeing `op ->' the current scope for name lookup
 >    should be `Outer' and in `Outer' there is no
 >    directly visible `Inner', so it should not compile!

This should compile, the type of 'op' is 'Outer::Other*' (not
'Outer' as you said) so the lookup for the 'Inner' after the '->'
happens in 'Outer::Other' (as well as in the scope of 'f').
The only class or namespace names visible in 'Outer::Other' (ignoring
implicit members) are 'Other' (meaning 'Outer::Other') and 'Inner'
(meaning 'Inter::Inner', the base class of 'Other').

 >    On the other hand one could say `Other' is derived
 >    from a base class named `Inner' no matter if it
 >    is visible right now and the member `i' is correctly
 >    qualified by the name of the base class where
 >    it does belong to, so it should compile o.k.!

No, the compiler has to lookup 'Inner' and be able to find it to know
which 'Inner' you are talking about, it is not allowed to guess or read minds.
There might be many gloabl or nested 'Inner's, some without 'i's, some that
'Other' is not derived from.

 > c) should compile ok since after seeing `op ->'
 >    the current scope for name lookup should be
 >    `Outer' and `Inner' should be visible from there
 >    when qualified by the directly visible `Inter'.
 >    So member `i' is uniquely and correctly qualified
 >    by `Other''s base `Inter::Inner'.

No, the type of 'op' is 'Outer::Other*' and 'Inter' is not a name
visible from 'Other'.  Two name lookups are done for the 'Inter' after
the '->':

The first depends on the type of 'op' and only considers 'Other' and its
base classes (and not the classes 'Other' is nested in).  The second
lookup is in the scope that the expression is in:  in this case the scope of
the function 'f', which can see only 'Outer' (and 'f' but 'f' is not a class
or namespace).  If the name was found by both lookups it would have to mean
the same thing.
---
[ 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: Kannan Chellappan <chellapk@nmasd.bel.alcatel.be>
Date: 1998/07/27
Raw View
Norbert Berzen wrote:

> Hello,
>
> can someone tell me if the following is well formed c++:
>
> struct Outer {
>
>   struct Inter {
>
>     struct Inner {
>
>       int i;
>
>     };
>
>   };
>
>   struct Other : public Inter::Inner {
>
>         // empty
>
>   };
>
> };
>
> int
> f (Outer::Other *op)
> {
>   op -> Inter::Inner::i = 0;
> }
>

I dont see any problem. The structure Inner can be accessed only through
Inter (as Inner is in the scope of Inter) and the structures Other and Inter
are in the same scope (that of Outer).

Did you face any problems ?
---
[ 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: sbnaran@fermi.ceg.uiuc.edu (Siemel Naran)
Date: 1998/07/28
Raw View
[edited a little]
>> struct Outer {
>>
>>   struct Inter {
>>     struct Inner { int i; };
>>   };
>>
>>   struct Other : public Inter::Inner { };
>>
>> };

Consider declaring classes out of line as this is good for
readability.

>> int
>> f (Outer::Other *op)
>> {
>>   op -> Inter::Inner::i = 0;
>> }


>I dont see any problem. The structure Inner can be accessed only through
>Inter (as Inner is in the scope of Inter) and the structures Other and Inter
>are in the same scope (that of Outer).

If "Outer" were a namespace, then since the declaration of the
function f(...) uses the namespace "Outer", the compiler pulls
in this namespace.  Then
     Inter::Inner::i
refers to
     Outer::Inter::Inner::i.

But "Outer" is a class, so does it get pulled in?  I don't think so,
because if it did get pulled in, the code below would compile.

void f(std::list<int>::iterator iter)
// this pulls in namespace std
// suppose it also pulls in std::list<int>
{
     value_type integer; // fine!
     // value_type ==> std::list<int>::value_type ==> int
}


So back to the original example, the 'namespace' Outer (which is
really a class) would only get pulled in function f(...) were
a member or static function of class Outer, or a member or static
function of one of the nested classes of class Outer (i.e. a member
or static of Outer::Inter or Outer::Inter::Inner).




Here's my correction.  Note that in this case, the scope resolution
is not really necessary.

>f (Outer::Other *op)
>{
>    op -> Inter::Inner::i = 0;

     op -> Outer::Inter::Inner::i = 0;




>Did you face any problems ?

The original code as written does not compile on g++ 2.7.2.3.


--
----------------------------------
Siemel B. Naran (sbnaran@uiuc.edu)
----------------------------------
---
[ 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              ]