Topic: typename keyword and derived template classes
Author: David Vandevoorde <daveed@vandevoorde.com>
Date: 1997/07/30 Raw View
Bill Gibbons wrote:
[...]
> template<class T> struct Base {
> typedef float X;
> };
>
> template<class T> struct Derived : Base<T> {
> X x; // ill-formed, but accepted by some compilers
> };
>
> template<> struct Base<int> {
> typedef double X;
> };
>
> Derived<long> d1; // d1.x has type "float"
>
> Derived<int> d2; // d2.x has type "float" - WRONG
Not if the names were bound at a point of instantiation,
which is what many older compilers do, I believe. If so,
however, they're likely to get a variation of your
example wrong (e.g., place a synonym in namespace scope).
To me, the #1 advantage of early binding of non-dependent
names is that many errors are caught at template definition
time, instead of (usually much later) instantiation time.
Daveed
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: jbuck@synopsys.com (Joe Buck)
Date: 1997/07/25 Raw View
Consider the following as a definition of the STL unary_negate:
(this is from the SGI STL).
template <class Predicate>
class unary_negate :
public unary_function<typename Predicate::argument_type, bool>
{
protected:
Predicate pred;
public:
explicit unary_negate(const Predicate& x) : pred(x) {}
bool operator()(const argument_type& x) const { return !pred(x); }
};
Is this correct C++ code (ignoring namespace and reserved-names issues)?
Specifically, is the use of argument_type in the definition of operator()
correct? Or must a line like the following be added:
typedef typename Predicate::argument_type argument_type;
[ Warning: I base the following on a version of aCC that is not the
latest release; apologies to aCC's authors if the following is obsolete ].
HP's aCC compiler requires a line of this type. The rule at the beginning
of [temp.res] says:
"A name used in a template is assumed not to name a type unless the
applicable name lookup finds a type name or the name is qualified by
the keyword typename."
However, it seems that the applicable name lookup in this case includes
the base class, unary_function<Predicate::argument_type,bool>, which
defines argument_type as a type. HP's interpretation seems to require
that all typedefs in base classes must be explicitly imported into any
template class that is a derived class with a "typedef typename". SGI's
STL would require thousands of changes to work under these rules.
I don't think this was the intent of the committee; we can't parse a
normal class without looking at the base class and I don't think templates
should be different. Comments?
--
-- Joe Buck http://www.synopsys.com/pubs/research/people/jbuck.html
Help stamp out Internet spam: see http://spam.abuse.net/spam/
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: bill@gibbons.org (Bill Gibbons)
Date: 1997/07/28 Raw View
In article <33D95918.819CB55A@vandevoorde.com>, daveed@vandevoorde.com wrote:
> Joe Buck wrote:
> > ... finding unqualified type names in dependent base classes ....
> >
> > I don't think this was the intent of the committee; we can't parse a
> > normal class without looking at the base class and I don't think
> > templates should be different. Comments?
>
> I think it's quite explicit in [temp.dep] 14.6.2/4.
>
> The rules for dependent and non-dependent name lookup were
> clarified relatively recently (July 1996 -- Stockholm; mostly
> the work of SGI contributors, BTW).
The intent of the lookup rules, including the fact that type names
in dependent base classes are not found in the initial name lookup,
has been clear for several years. Some vendors have not yet updated
their compilers, and some are deliberately accepting incorrecct old code.
Consider what happens with explicit specialization with these compilers:
template<class T> struct Base {
typedef float X;
};
template<class T> struct Derived : Base<T> {
X x; // ill-formed, but accepted by some compilers
};
template<> struct Base<int> {
typedef double X;
};
Derived<long> d1; // d1.x has type "float"
Derived<int> d2; // d2.x has type "float" - WRONG
The cost of accepting incorrect old code may be incorrectly compiling
new code.
-- Bill Gibbons
bill@gibbons.org
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]