Topic: template parameter identifier access specification??
Author: James Kuyper <kuyper@wizard.net>
Date: Mon, 15 Jan 2001 20:19:49 CST Raw View
Daniel Frey wrote:
>
> James Kuyper wrote:
> >
> > Daniel Frey wrote:
...
> the "trick" above. Now I wonder if I use the above
>
> template< typename T_ > class X
> {
> private:
> typedef T_ T;
>
> // Do not use T_ here...
> };
>
> If there is any difference between this T and the "original" T (without
> the indirection). A colleague told me that compilers treat template
> parameters very different than typedefs, so I wonder if it makes any
> difference for me as a user of it.
It makes a LOT of difference.
Member typedefs have class scope. That means that they are visible
anywhere that any other member of the class is. They can be referred to
using explicitly qualified names (such as MyClass::my_typedef) anywhere
that the class definition is available, and they can be referred to
without qualification inside the class definition and in member
definitions that appear outside the class definition.
Class template parameters are visible only in the template definition.
They can't be referred to from outside by use of qualification. They
aren't even visible in member definitions, if you choose to move those
definitions outside the definition of the class itself (note - allowing
members to be defined outside the class definition is a fairly new
feature of C++, your compiler may not support it yet). According to
14.5.1p3, "The names of the template parameters used in the definition
of the member may be different from the template parameter names used in
the class template definition." Example:
template<class T, class U> class Mine
{
size_t member_func();
}
template<class V, class W> Mine::member_func() {
// V means the same thing in this definition that
// T meant in the definition of Mine.
return sizeof(V);
}
Note that member functions, member classes, member templates and static
data members can all be defined outside the class definition. However,
non-static data members and member typedefs must appear in the class
definition itself.
> > > but I cannot use T when deriving from another class (template< typename
> > > _T > class X : public Y< _T >). I have to use _T which is IMO
> > > inconsistent. ...
> >
> > Why do you think that's inconsistent? 'T' is a member typedef with class
> > scope; it's not visible at the point where Y<_T> is used, because that
> > point isn't in class scope.
>
> A real-world example from one of my sources:
...
> This would be more "consistent" as there are no additional types T and U
> with a useless (implicit) private access specification. This would allow
> me to express straight forward what I want instead of hacking around.
I'm just saying that there's no inconsistency in the standard. It's
perfectly clear on why this is happening. I can agree that there's some
inconvenience, but that's a different issue.
> > keywords? It might have to do with the rules for name lookup, or
> > overload resolution, or some completely different characteristic of the
> > language.
>
> This is part of my question: How are template parameters handled by the
> name lookup. Are they compatible to "private"-typedefs or are there
> different rules?
Very different rules, as described above.
---
[ 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 ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Thu, 11 Jan 2001 17:50:29 GMT Raw View
Hi,
I wonder how template parameters are handled regarding their access
specification.
template< typename T > class X
{
// ...
}
is the usual implementation. Now I often use something similar to this:
template< typename _T > class X
{
public:
typedef _T T;
// ... (not using _T)
};
but I cannot use T when deriving from another class (template< typename
_T > class X : public Y< _T >). I have to use _T which is IMO
inconsistent. I also wonder if the second example is equivalent to the
first if I replace 'public' with 'private'. My experience with
specializations suggest that their is some special behaviour involved
that cannot be expressed by either 'private', 'protected' or 'public'. I
tried to find something in the bible (The C++ programming language,
german special edition), but I found nothing. Can someone please explain
what are the correct rules for it?
While we are at it: Would it make sense to allow a syntax like this:
template< public typename T > class X
{
// ...
};
to allow X<...>::T to be used? I often have a typedef for a template and
it would be easier to access some types that way. Could also be useful
for containers (key_type, value_type, ...), right?
Regards, Daniel
--
Daniel Frey wir machen anleger
aixigo AG - financial research and education
Schlo=DF-Rahe-Stra=DFe 15, 52072 Aachen, Germany
phone: +49 (0)241 93 67 37 - 42 fax: - 99
daniel.frey@aixigo.de http://www.aixigo.de
---
[ 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 ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: James Kuyper <kuyper@wizard.net>
Date: Thu, 11 Jan 2001 19:19:41 CST Raw View
Daniel Frey wrote:
>
> Hi,
>
> I wonder how template parameters are handled regarding their access
> specification.
>
> template< typename T > class X
> {
> // ...
> }
>
> is the usual implementation. Now I often use something similar to this:
>
> template< typename _T > class X
> {
> public:
> typedef _T T;
>
> // ... (not using _T)
> };
Note: names starting with an underscore followed by a capital letter are
reserved for any use by the implementation (17.4.3.1.2p1). Therefore,
this code has undefined behavior (17.4.3.1p1).
> but I cannot use T when deriving from another class (template< typename
> _T > class X : public Y< _T >). I have to use _T which is IMO
> inconsistent. ...
Why do you think that's inconsistent? 'T' is a member typedef with class
scope; it's not visible at the point where Y<_T> is used, because that
point isn't in class scope.
> ... I also wonder if the second example is equivalent to the
> first if I replace 'public' with 'private'. My experience with
No. The "private" keyword would restrict the accessibility of 'T' to the
scope of X itself. With the public keyword, 'T' would also be accessible
in derived classes and even by ordinary users of X.
> specializations suggest that their is some special behaviour involved
> that cannot be expressed by either 'private', 'protected' or 'public'. I
> tried to find something in the bible (The C++ programming language,
> german special edition), but I found nothing. Can someone please explain
> what are the correct rules for it?
Your question is quite unclear. Can you give an example of what behavior
you're referring to that you think can't be expressed by the access
keywords? Possibly that behavior has nothing to with the access
keywords? It might have to do with the rules for name lookup, or
overload resolution, or some completely different characteristic of the
language.
---
[ 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 ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]
Author: Daniel Frey <daniel.frey@aixigo.de>
Date: Fri, 12 Jan 2001 10:44:13 CST Raw View
James Kuyper wrote:
>
> Daniel Frey wrote:
> >
> > Hi,
> >
> > I wonder how template parameters are handled regarding their access
> > specification.
> >
> > template< typename T > class X
> > {
> > // ...
> > }
> >
> > is the usual implementation. Now I often use something similar to this:
> >
> > template< typename _T > class X
> > {
> > public:
> > typedef _T T;
> >
> > // ... (not using _T)
> > };
>
> Note: names starting with an underscore followed by a capital letter are
> reserved for any use by the implementation (17.4.3.1.2p1). Therefore,
> this code has undefined behavior (17.4.3.1p1).
Sorry if my question was poorly expressed. I really meant that the _T in
the above code should be read as an implementation specific detail (this
is what I tried to express by "(not using _T)". OK, let me try it again
:)
If I have
template< [ACCESS] typename T > class X
{
};
template< typename U > class Y : public X< U >
{
// Is T visible here? No. This would be the "protected"-case.
};
// Is X::T visible here? No. This would be the "public"-case.
Currently, you cannot provide anything for [ACCESS], you'll have to use
the "trick" above. Now I wonder if I use the above
template< typename T_ > class X
{
private:
typedef T_ T;
// Do not use T_ here...
};
If there is any difference between this T and the "original" T (without
the indirection). A colleague told me that compilers treat template
parameters very different than typedefs, so I wonder if it makes any
difference for me as a user of it.
> > but I cannot use T when deriving from another class (template< typename
> > _T > class X : public Y< _T >). I have to use _T which is IMO
> > inconsistent. ...
>
> Why do you think that's inconsistent? 'T' is a member typedef with class
> scope; it's not visible at the point where Y<_T> is used, because that
> point isn't in class scope.
A real-world example from one of my sources:
template< typename T, typename U > class VectorReceiver : public
Receiver< T, U >
{
protected:
typedef T KeyType;
typedef U DataType;
std::vector< std::pair< KeyType, DataType > >& vector_;
// ...
};
I'd like to write
template< protected typename KeyType, protected typename DataType >
class VectorReceiver : public Receiver< KeyType, DataType >
{
protected:
std::vector< std::pair< KeyType, DataType > >& vector_;
// ...
};
This would be more "consistent" as there are no additional types T and U
with a useless (implicit) private access specification. This would allow
me to express straight forward what I want instead of hacking around.
> keywords? It might have to do with the rules for name lookup, or
> overload resolution, or some completely different characteristic of the
> language.
This is part of my question: How are template parameters handled by the
name lookup. Are they compatible to "private"-typedefs or are there
different rules?
Regards, Daniel
--
Daniel Frey wir machen anleger
aixigo AG - financial research and education
Schlo -Rahe-Stra e 15, 52072 Aachen, Germany
phone: +49 (0)241 93 67 37 - 42 fax: - 99
daniel.frey@aixigo.de http://www.aixigo.de
---
[ 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 ]
[ Note that the FAQ URL has changed! Please update your bookmarks. ]