Topic: Name lookup for a template parameter and a base class.


Author: "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm>
Date: Tue, 10 Apr 2001 14:45:40 GMT
Raw View
While copy/pasting I have lost the template instantiation code which might
lead to obscurity of the example. I am terribly sorry for that (Mr. Bonnard,
you were absolutely right). There is missing code below.

> Let us consider the following code:
> [Example:
> class A {
> public:
>  enum {i};
> };
>
> template <class T>
> class C : private T {
>  class B {
>  public:
>      B() {T::i;} // AAAA
>  } b;
int
main()
{
 C<A> c;
}

> };
> -- end example]
>
> The majority of compilers treat T at AAAA as a name of the type which is
> defined by the template parameter rather then the base class name. No
doubt
> it change the semantics a little: the program is well-formed in the first
> case and ill-formed in the second one.
>
> Please, give me a reference at the Standard which will clarify this issue.
I
> failed to do it by myself.

Thank you in advance,
with regards,
Michael Kochetkov.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Gennaro Prota" <gennaro_prota@my-deja.com>
Date: Tue, 10 Apr 2001 14:46:30 GMT
Raw View
"Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in
news:3ad224aa@news.telekom.ru...
>
> "Valentin Bonnard" <bonnard@clipper.ens.fr> wrote in message
> news:200104091943.VAA25063@brick.ens.fr...
> > "Michael Kochetkov"  wrote:
> > > Let us consider the following code:
> > > [Example:
> > > class A {
> > > public:
> > >  enum {i};
> > > };
> > >
> > > template <class T>
> > > class C : private T {
> > >  class B {
> > >  public:
> > >      B() {T::i;} // AAAA
> > >  } b;
> > > };
> > > -- end example]
> > >
> > > The majority of compilers treat T at AAAA as a name of the type which
is
> > > defined by the template parameter rather then the base class name.
> >
> > ???
> >
> > ``T'' and ``A'' aren't the same names (because, well, T is T and A is
A).
> >
> > How would any use of the name T refer to A ? It makes no sens !
> I am not sure I completely understand what are you talking about but as
far
> as can guess this example will look better for you:
> [Example:
> class T {
> public:
>  enum {i};
> };
>
> template <class T> // EEEE
> class C : private T { // DDDD
>  class B {
>  public:
>      B() {T::i;} // AAAA
>  } b;
> };
> -- end example]
> You can say now that T at EEEE and T at DDDD are the different things.
There
> is no doubt in it. But is there a rule in the Standard which forces a
> compiler to prefer T at EEEE to T at DDDD at AAAA (I agree that it sounds
> awfully but I hope it is understandable)? That is what I ask about.
>
> With regards,
> Michael Kochetkov.
>

According to my understanding of the standard (and of your question ;-)),
the answer is in clause 14.6.1, par.3:
"The scope of a template-parameter extends from its point of declaration
until the end of its template. A template-parameter hides any entity with
the same name in the enclosing scope."

I hope this is what you were looking for! :-)

                                                             Gennaro Prota.







---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Tue, 10 Apr 2001 17:37:49 GMT
Raw View
"Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in message
news:3ad1d80d@news.telekom.ru...
>
> "Anthony Williams" <anthwil@nortelnetworks.com> wrote in message
> news:9arvu6$6gnrb$1@ID-49767.news.dfncis.de...
> > "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in
message
> > news:3acf6164@news.telekom.ru...
> > > Let us consider the following code:
> > > [Example:
> > > class A {
> > > public:
> > >  enum {i};
> > > };
> > >
> > > template <class T>
> > > class C : private T {
> > >  class B {
> > >  public:
> > >      B() {T::i;} // AAAA
> > >  } b;
> > > };
> > > -- end example]
> > >
> > > The majority of compilers treat T at AAAA as a name of the type which
is
> > > defined by the template parameter rather then the base class name. No
> > doubt
> > > it change the semantics a little: the program is well-formed in the
> first
> > > case and ill-formed in the second one.
> > >
> > > Please, give me a reference at the Standard which will clarify this
> issue.
> > I
> > > failed to do it by myself.
> > >
> >
> > T::i is a dependent name (14.6.2), and is thus assumed to refer to a
value
> > rather than a type (14.6p2).
> Right.
>
> >
> > The base class of C is a dependent name. Thus it is not used for name
> lookup
> > within the template definition (14.6.2p3), and it cannot hide names
> 14.6.2p3 says about the definition of a class template and about the
> definition of a member of such a template.
> I.e. it says that in the code
> typedef double A;
> template<class T> B {
>     typedef int A;
> };
> template<class T> struct X : B<T> {
>     A a; // a has type double
> };
> the name A is not looked in the B<T>'s scope.
>
> > (14.6.2p4)
> 14.6.2p4 says about the member of a parameterozed class that cannot hide
...
> etc.
>
> > I agree with "the majority of compilers" that this is well-formed, and
> T::i
> > always refers to ::A::i rather than C<A>::A::i, for the instantiation
> C<A>.
> >
> > Why would you ever want the other interpretation?
> We are talking about the nested class definition in my example above. It
is
> neither definition of a class template from 14.6.2p3 nor a member
definition
> from 14.6.2/3 and 14.6.2/4. So IMO a compiler  may consider private T
access
> rights while analysing the C::B declaration/definition. C and C::B are
> unrelated classes and IMO 14.6.2/3 and 14.6.2/4 are not applicable for the
> example we are talking about.


class B is a Member class of a class template (14.5.1.2). IMO it is
therefore a member of the template, and thus forms part of the definition of
the template. T::i is thus a dependent name within a template definition,
which thus resolves to a declaration that is visible at the point of the
template definition (14.6.4).

The only declaration of A visible at the point of the template definition is
::A.

The base class of C depends on the template parameter T (it IS T). Thus the
base class scope is not examined until the template is instantiated
(14.6.2p3), which means that in C<A>, T::i always refers to ::A::i, never
C<A>::A::i.

It really isn't clear, but then none of "14 Templates" is particularly
clear.

> I want the other interpretation (the reason I write here) because the same
> non-parameterized code:
> class A {
> public:
>  enum {i};
> };
>
> class C : private A {
>  class B {
>  public:
>      B() {A::i;}
>  } b;
> };
> is ill-formed. While the magic of the templates makes it well-formed. I
> would not say that is strange but it looks like a little bit inconsistent
> (or even a defect).

I agree it is inconsistent. Templates often do odd things to name lookup,
and this is one of them. If you don't like it, raise a defect report.
However, I don't agree with the other responder that the non-template code
is the defect, and I really wouldn't fancy trying to change the template
name resolution, as that could easily have far-reaching effects.

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm>
Date: Tue, 10 Apr 2001 20:29:43 GMT
Raw View
> > > > Let us consider the following code:
> > > > [Example:
> > > > class A {
> > > > public:
> > > >  enum {i};
> > > > };
> > > >
> > > > template <class T>
> > > > class C : private T {
> > > >  class B {
> > > >  public:
> > > >      B() {T::i;} // AAAA
> > > >  } b;
> > > > };
// Here goes the missing part.
int
main()
{
 C<A> c;
}

> > > > -- end example]

> class B is a Member class of a class template (14.5.1.2). IMO it is
> therefore a member of the template, and thus forms part of the definition
of
> the template.
I read you words as the class B definition is the part of the definition of
the template because you consider T::i below (which appears in the B's
definition indeed). Sorry, but I do not agree that class B is the part of
the definition of the template. The code:
class A {
public:
 enum {i};
};

template <class T> class C : private T {
 class B;
};

int main() {  C<A> c; }
is well-formed, i.e. C is complete class despite B's definition is missing.

> T::i is thus a dependent name within a template definition,
> which thus resolves to a declaration that is visible at the point of the
> template definition (14.6.4).
But I am inclined to agree with you on this point. If 14.5.1.2 allows us to
treat B's declatation/definition as a member that will be the way the things
are going... I suppose...

> The only declaration of A visible at the point of the template definition
is
> ::A.
Sorry, do you mean that the only declaration of T visible at the point of
the template definition is T that is the template parameter rather then the
base? We are talking about AAAA above, are not we? BTW in my original
message I have considered template parameter T::i and base T::i at the point
of instantiation. When C::B definition is looked throught by a compiler it
knows nothing about A as the template argument, does it?
Or do you say about the point of instantiation where A takes place (and "the
point of the template definition" is a misprint)? But in this case the templ
ate argument A (I wonder if I use correct words) shall hide global ::A.
Anyway IMO we may consider either A which is the template argument or A
which is base but not the global ::A. We agreed now that the base shall not
be considered as far as B is the member.

[The rest we are agreed upon is skipped.]

Thank you, you were very helpful.

With regards,
Michael Kochetkov.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Gennaro Prota" <gennaro_prota@my-deja.com>
Date: Wed, 11 Apr 2001 15:47:23 GMT
Raw View
"Anthony Williams" <anthwil@nortelnetworks.com> wrote:

> > > > Let us consider the following code:
> > > > [Example:
> > > > class A {
> > > > public:
> > > >  enum {i};
> > > > };
> > > >
> > > > template <class T>
> > > > class C : private T {
> > > >  class B {
> > > >  public:
> > > >      B() {T::i;} // AAAA
> > > >  } b;
> > > > };
> > > > -- end example]
> > > >
[snip]

>
> class B is a Member class of a class template (14.5.1.2). IMO it is
> therefore a member of the template, and thus forms part of the definition
of
> the template. T::i is thus a dependent name within a template definition,
> which thus resolves to a declaration that is visible at the point of the
> template definition (14.6.4).
>
> The only declaration of A visible at the point of the template definition
is
> ::A.
>
> The base class of C depends on the template parameter T (it IS T). Thus
the
> base class scope is not examined until the template is instantiated
> (14.6.2p3), which means that in C<A>, T::i always refers to ::A::i, never
> C<A>::A::i.
>
> It really isn't clear, but then none of "14 Templates" is particularly
> clear.
>
> > I want the other interpretation (the reason I write here) because the
same
> > non-parameterized code:
> > class A {
> > public:
> >  enum {i};
> > };
> >
> > class C : private A {
> >  class B {
> >  public:
> >      B() {A::i;}
> >  } b;
> > };
> > is ill-formed. While the magic of the templates makes it well-formed. I
> > would not say that is strange but it looks like a little bit
inconsistent
> > (or even a defect).
>
> I agree it is inconsistent. Templates often do odd things to name lookup,
> and this is one of them. If you don't like it, raise a defect report.
> However, I don't agree with the other responder that the non-template code
> is the defect, and I really wouldn't fancy trying to change the template
> name resolution, as that could easily have far-reaching effects.
>

Excellent post! I never thought carefully about these 'name lookup
oddities'.
Please, ignore my previous post on this subject, because I misinterpreted
Michael's question (I stupidly thought of  a situation where the name of the
base class of C was "T" itself, like the following:

class T {
public:
 enum {i};
};

template <class T>
class C : private T {

 class B {
 public:
  B() {T::i;} // AAAA
 } b;
};

)

 Sorry for the misunderstanding. :-)

                                                  Gennaro.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Thu, 12 Apr 2001 21:24:43 GMT
Raw View
"Michael Kochetkov"  wrote:
> While copy/pasting I have lost the template instantiation code which might
> lead to obscurity of the example. I am terribly sorry for that (Mr. Bonnard,
> you were absolutely right). There is missing code below.
>
>> Let us consider the following code:
>> [Example:
>> class A {
>> public:
>>  enum {i};
>> };
>>
>> template <class T>
>> class C : private T {
>>  class B {
>>  public:
>>      B() {T::i;} // AAAA
>>  } b;
> int
> main()
> {
>  C<A> c;
> }
>
>> };
>> -- end example]
>>
>> The majority of compilers treat T at AAAA as a name of the type which is
>> defined by the template parameter rather then the base class name. No
>> doubt
>> it change the semantics a little: the program is well-formed in the first
>> case and ill-formed in the second one.

I still don't understand the question, and will repeat my
previous answer. There is no C<A>::T member, only C<A>::A.
So, while T in the scope of the only instantiation of C is
really A, the name T doesn't refer to A, but to the template
parameter.

This is no different from the non-template case.

--

Valentin Bonnard

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "TiTi" <titi_@skynet.be>
Date: Fri, 13 Apr 2001 16:13:26 GMT
Raw View
Michael Kochetkov <Michael.Kochetkov@trustworks.commmm> schreef in
berichtnieuws 3acf6164@news.telekom.ru...
> Let us consider the following code:
> [Example:
> class A {
> public:
>  enum {i};
> };
> template <class T>
> class C : private T {
>  class B {
>  public:
>      B() {T::i;} // AAAA
>  } b;
> };
> -- end example]

> The majority of compilers treat T at AAAA as a name of the type which is
> defined by the template parameter rather then the base class name. No
doubt
> it change the semantics a little: the program is well-formed in the first
> case and ill-formed in the second one.

IMO, The AAAA line actually reads:

    B() { ::T::i; } // AAAA

Maybe you should try to explicitely qualify, that is, refer to the base
class subobject, as in:

    B() { C<T>::T::i; }


TiTi


---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Sun, 15 Apr 2001 01:06:53 GMT
Raw View
"TiTi"  wrote:

> Michael Kochetkov <Michael.Kochetkov@trustworks.commmm> schreef in
> berichtnieuws 3acf6164@news.telekom.ru...
>> Let us consider the following code:
>> [Example:
>> class A {
>> public:
>>  enum {i};
>> };
>> template <class T>
>> class C : private T {
>>  class B {
>>  public:
>>      B() {T::i;} // AAAA
>>  } b;
>> };
>> -- end example]

> IMO, The AAAA line actually reads:
>
>     B() { ::T::i; } // AAAA

It has been pointed out before that ::T is hiden by the template
parameter T, so no, T doesn't refer to ::T.

> Maybe you should try to explicitely qualify, that is, refer to the base
> class subobject, as in:
>
>     B() { C<T>::T::i; }

The inheritance is private, B isn't a friend of C, so B has
no access to the inheritance, so this code is ill-formed.

Michael Kochetkov certainly knows how to explicitly qualify
names, but he doesn't _want_ to refer to the base class
(which is pointless in this case).

He wants to know what the unqualified name T refers to, and
whether the code is well-formed or not.

--

Valentin Bonnard

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm>
Date: Sun, 15 Apr 2001 01:07:38 GMT
Raw View
> > Let us consider the following code:
> > [Example:
> > class A {
> > public:
> >  enum {i};
> > };
> > template <class T>
> > class C : private T {
> >  class B {
> >  public:
> >      B() {T::i;} // AAAA
> >  } b;
> > };
> > -- end example]
>
> > The majority of compilers treat T at AAAA as a name of the type which is
> > defined by the template parameter rather then the base class name. No
> doubt
> > it change the semantics a little: the program is well-formed in the
first
> > case and ill-formed in the second one.
>
> IMO, The AAAA line actually reads:
>
>     B() { ::T::i; } // AAAA
No, you are wrong. A template parameter hides names from the enclosing
scope. It actually reads:
B() { template parameter T::i; } // AAAA

With regards,
Michael Kochetkov.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm>
Date: Sun, 8 Apr 2001 17:14:10 GMT
Raw View
Let us consider the following code:
[Example:
class A {
public:
 enum {i};
};

template <class T>
class C : private T {
 class B {
 public:
     B() {T::i;} // AAAA
 } b;
};
-- end example]

The majority of compilers treat T at AAAA as a name of the type which is
defined by the template parameter rather then the base class name. No doubt
it change the semantics a little: the program is well-formed in the first
case and ill-formed in the second one.

Please, give me a reference at the Standard which will clarify this issue. I
failed to do it by myself.

Thank you in advance,
with regards,
Michael Kochetkov.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Anthony Williams" <anthwil@nortelnetworks.com>
Date: Mon, 9 Apr 2001 14:09:13 GMT
Raw View
"Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in message
news:3acf6164@news.telekom.ru...
> Let us consider the following code:
> [Example:
> class A {
> public:
>  enum {i};
> };
>
> template <class T>
> class C : private T {
>  class B {
>  public:
>      B() {T::i;} // AAAA
>  } b;
> };
> -- end example]
>
> The majority of compilers treat T at AAAA as a name of the type which is
> defined by the template parameter rather then the base class name. No
doubt
> it change the semantics a little: the program is well-formed in the first
> case and ill-formed in the second one.
>
> Please, give me a reference at the Standard which will clarify this issue.
I
> failed to do it by myself.
>

T::i is a dependent name (14.6.2), and is thus assumed to refer to a value
rather than a type (14.6p2).

The base class of C is a dependent name. Thus it is not used for name lookup
within the template definition (14.6.2p3), and it cannot hide names
(14.6.2p4)

I agree with "the majority of compilers" that this is well-formed, and T::i
always refers to ::A::i rather than C<A>::A::i, for the instantiation C<A>.

Why would you ever want the other interpretation?

Anthony
--
Anthony Williams
Software Engineer, Nortel Networks Optoelectronics
The opinions expressed in this message are not necessarily those of my
employer



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: bonnard@clipper.ens.fr (Valentin Bonnard)
Date: Mon, 9 Apr 2001 19:59:33 GMT
Raw View
"Michael Kochetkov"  wrote:
> Let us consider the following code:
> [Example:
> class A {
> public:
>  enum {i};
> };
>
> template <class T>
> class C : private T {
>  class B {
>  public:
>      B() {T::i;} // AAAA
>  } b;
> };
> -- end example]
>
> The majority of compilers treat T at AAAA as a name of the type which is
> defined by the template parameter rather then the base class name.

???

``T'' and ``A'' aren't the same names (because, well, T is T and A is A).

How would any use of the name T refer to A ? It makes no sens !

--

Valentin Bonnard

---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm>
Date: Mon, 9 Apr 2001 20:29:54 GMT
Raw View
"Anthony Williams" <anthwil@nortelnetworks.com> wrote in message
news:9arvu6$6gnrb$1@ID-49767.news.dfncis.de...
> "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in message
> news:3acf6164@news.telekom.ru...
> > Let us consider the following code:
> > [Example:
> > class A {
> > public:
> >  enum {i};
> > };
> >
> > template <class T>
> > class C : private T {
> >  class B {
> >  public:
> >      B() {T::i;} // AAAA
> >  } b;
> > };
> > -- end example]
> >
> > The majority of compilers treat T at AAAA as a name of the type which is
> > defined by the template parameter rather then the base class name. No
> doubt
> > it change the semantics a little: the program is well-formed in the
first
> > case and ill-formed in the second one.
> >
> > Please, give me a reference at the Standard which will clarify this
issue.
> I
> > failed to do it by myself.
> >
>
> T::i is a dependent name (14.6.2), and is thus assumed to refer to a value
> rather than a type (14.6p2).
Right.

>
> The base class of C is a dependent name. Thus it is not used for name
lookup
> within the template definition (14.6.2p3), and it cannot hide names
14.6.2p3 says about the definition of a class template and about the
definition of a member of such a template.
I.e. it says that in the code
typedef double A;
template<class T> B {
    typedef int A;
};
template<class T> struct X : B<T> {
    A a; // a has type double
};
the name A is not looked in the B<T>'s scope.

> (14.6.2p4)
14.6.2p4 says about the member of a parameterozed class that cannot hide ...
etc.

> I agree with "the majority of compilers" that this is well-formed, and
T::i
> always refers to ::A::i rather than C<A>::A::i, for the instantiation
C<A>.
>
> Why would you ever want the other interpretation?
We are talking about the nested class definition in my example above. It is
neither definition of a class template from 14.6.2p3 nor a member definition
from 14.6.2/3 and 14.6.2/4. So IMO a compiler  may consider private T access
rights while analysing the C::B declaration/definition. C and C::B are
unrelated classes and IMO 14.6.2/3 and 14.6.2/4 are not applicable for the
example we are talking about.
I want the other interpretation (the reason I write here) because the same
non-parameterized code:
class A {
public:
 enum {i};
};

class C : private A {
 class B {
 public:
     B() {A::i;}
 } b;
};
is ill-formed. While the magic of the templates makes it well-formed. I
would not say that is strange but it looks like a little bit inconsistent
(or even a defect).

Thank you for your reply,
with regards,
Michael Kochetkov.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Ruslan Abdikeev" <ruslan_abdikeevRemoveIt@hotmail.com>
Date: Mon, 9 Apr 2001 22:11:53 GMT
Raw View
Michael,

IMHO the inconsistency or even defect is NOT with parametrized case.
Defect is that code becomes ill-formed or well-formed even in this case:

class A {
public:
 enum {i};
};

class C /*: private A*/ { //When commented - well-formed, when uncommented -
ill-formed
 class B {
 public:
     B() {A::i;}
 } b;
};

Sincerely,

Ruslan Abdikeev
VR-1 Entertainment Corp.
www.vr1.com



"Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in message
news:3ad1d80d@news.telekom.ru...
>
> "Anthony Williams" <anthwil@nortelnetworks.com> wrote in message
> news:9arvu6$6gnrb$1@ID-49767.news.dfncis.de...
> > "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm> wrote in
message
> > news:3acf6164@news.telekom.ru...
> > > Let us consider the following code:
> > > [Example:
> > > class A {
> > > public:
> > >  enum {i};
> > > };
> > >
> > > template <class T>
> > > class C : private T {
> > >  class B {
> > >  public:
> > >      B() {T::i;} // AAAA
> > >  } b;
> > > };
> > > -- end example]
> > >
> > > The majority of compilers treat T at AAAA as a name of the type which
is
> > > defined by the template parameter rather then the base class name. No
> > doubt
> > > it change the semantics a little: the program is well-formed in the
> first
> > > case and ill-formed in the second one.
> > >
> > > Please, give me a reference at the Standard which will clarify this
> issue.
> > I
> > > failed to do it by myself.
> > >
> >
> > T::i is a dependent name (14.6.2), and is thus assumed to refer to a
value
> > rather than a type (14.6p2).
> Right.
>
> >
> > The base class of C is a dependent name. Thus it is not used for name
> lookup
> > within the template definition (14.6.2p3), and it cannot hide names
> 14.6.2p3 says about the definition of a class template and about the
> definition of a member of such a template.
> I.e. it says that in the code
> typedef double A;
> template<class T> B {
>     typedef int A;
> };
> template<class T> struct X : B<T> {
>     A a; // a has type double
> };
> the name A is not looked in the B<T>'s scope.
>
> > (14.6.2p4)
> 14.6.2p4 says about the member of a parameterozed class that cannot hide
...
> etc.
>
> > I agree with "the majority of compilers" that this is well-formed, and
> T::i
> > always refers to ::A::i rather than C<A>::A::i, for the instantiation
> C<A>.
> >
> > Why would you ever want the other interpretation?
> We are talking about the nested class definition in my example above. It
is
> neither definition of a class template from 14.6.2p3 nor a member
definition
> from 14.6.2/3 and 14.6.2/4. So IMO a compiler  may consider private T
access
> rights while analysing the C::B declaration/definition. C and C::B are
> unrelated classes and IMO 14.6.2/3 and 14.6.2/4 are not applicable for the
> example we are talking about.
> I want the other interpretation (the reason I write here) because the same
> non-parameterized code:
> class A {
> public:
>  enum {i};
> };
>
> class C : private A {
>  class B {
>  public:
>      B() {A::i;}
>  } b;
> };
> is ill-formed. While the magic of the templates makes it well-formed. I
> would not say that is strange but it looks like a little bit inconsistent
> (or even a defect).
>
> Thank you for your reply,
> with regards,
> Michael Kochetkov.
>
>
>
> ---
> [ 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://www.research.att.com/~austern/csc/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://www.research.att.com/~austern/csc/faq.html                ]





Author: "Michael Kochetkov" <Michael.Kochetkov@trustworks.commmm>
Date: Tue, 10 Apr 2001 00:35:34 GMT
Raw View
"Valentin Bonnard" <bonnard@clipper.ens.fr> wrote in message
news:200104091943.VAA25063@brick.ens.fr...
> "Michael Kochetkov"  wrote:
> > Let us consider the following code:
> > [Example:
> > class A {
> > public:
> >  enum {i};
> > };
> >
> > template <class T>
> > class C : private T {
> >  class B {
> >  public:
> >      B() {T::i;} // AAAA
> >  } b;
> > };
> > -- end example]
> >
> > The majority of compilers treat T at AAAA as a name of the type which is
> > defined by the template parameter rather then the base class name.
>
> ???
>
> ``T'' and ``A'' aren't the same names (because, well, T is T and A is A).
>
> How would any use of the name T refer to A ? It makes no sens !
I am not sure I completely understand what are you talking about but as far
as can guess this example will look better for you:
[Example:
class T {
public:
 enum {i};
};

template <class T> // EEEE
class C : private T { // DDDD
 class B {
 public:
     B() {T::i;} // AAAA
 } b;
};
-- end example]
You can say now that T at EEEE and T at DDDD are the different things. There
is no doubt in it. But is there a rule in the Standard which forces a
compiler to prefer T at EEEE to T at DDDD at AAAA (I agree that it sounds
awfully but I hope it is understandable)? That is what I ask about.

With regards,
Michael Kochetkov.



---
[ 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://www.research.att.com/~austern/csc/faq.html                ]