Topic: Rationale for "this->" in template derived classes?
Author: pjl.removethis@removethistoo.mac.com ("Paul J. Lucas")
Date: Thu, 22 Apr 2004 19:05:59 +0000 (UTC) Raw View
In reading over the changes to g++ 3.4.0, I came across the
example below. Can somebody explain why this is in the C++
standard (presumeably, since g++ purports to implement the
standard)?
Why are the rules for template classes different from ordinary
classes?
- Paul
From <http://gcc.gnu.org/gcc-3.4/changes.html>, C++ section,
4th bullet:
In a template definition, unqualified names will no longer find members of a
dependent base. For example,
template <typename T> struct B {
int m;
int n;
int f ();
int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
void g ()
{
m = 0; // error
f (); // error
n = 0; // ::n is modified
g (); // ::g is called
}
};
You must make the names dependent by prefixing them with this->. Here is the
corrected definition of C<T>::g,
template <typename T> void C<T>::g ()
{
this->m = 0;
this->f ();
this->n = 0
this->g ();
}
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: rogero@howzatt.demon.co.uk ("Roger Orr")
Date: Thu, 22 Apr 2004 23:38:47 +0000 (UTC) Raw View
""Paul J. Lucas"" <pjl.removethis@removethistoo.mac.com> wrote in message
news:1nShc.54253$xn6.9864@newssvr25.news.prodigy.com...
> In reading over the changes to g++ 3.4.0, I came across the
> example below. Can somebody explain why this is in the C++
> standard (presumeably, since g++ purports to implement the
> standard)?
>
> Why are the rules for template classes different from ordinary
> classes?
The idea is to avoid surprises. The difficulty with templated base classes
is that the template could be explicitly specialized.
For an example, see "C++ Templates The Complete Guide" by Josuttis and
Vandevoorde p137:
HTH,
Roger Orr
--
MVP in C++ at www.brainbench.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Fri, 23 Apr 2004 04:52:44 +0000 (UTC) Raw View
pjl.removethis@removethistoo.mac.com ("Paul J. Lucas") writes:
> In reading over the changes to g++ 3.4.0, I came across the
> example below. Can somebody explain why this is in the C++
> standard (presumeably, since g++ purports to implement the
> standard)?
g++ does *not* purport to implement the standard. It purports to get
very much closer with each release. :-) Amoung other things, they
do not claim to implement export.
> Why are the rules for template classes different from ordinary
> classes?
You can find the reasoning behind the decision in D&E, 15.10.2 .
Alternatively, I made an attempt to explain some facets of the
situation a few days ago : http://xrl.us/bxe3 in a thread on
comp.lang.c++.moderated, but I'm not really an expert. :-)
>
> - Paul
>
> From <http://gcc.gnu.org/gcc-3.4/changes.html>, C++ section,
> 4th bullet:
>
> In a template definition, unqualified names will no longer find members of a
> dependent base. For example,
>
> template <typename T> struct B {
> int m;
> int n;
> int f ();
> int g ();
> };
> int n;
> int g ();
> template <typename T> struct C : B<T> {
Since template specialization allows different specializations of B
to have different members, depenending on T, it is not possible
to look up member names in B<T> until T is known. T is not known
when the definition is compiled; it is decided at the point of
instantiation. But postponing name lookup until the point of
instantiation has several problems:
(a) Certain classes of errors are not dectable. Ever see template
code which is wrong, but 'compiles' anyway, simply because
the template is never instantiated with the right parameters?
I have.
(b) It provides no language-supported way to enforce seperation
between interface and implementation (this is the facet I
explain in the link above).
So C++ has a notion of 'dependent name', which is rigorously defined
in 14.6.2.
But looking up names in depenendent base classes would make all names
depenendent, which would eliminate the value of such a notion.
> void g ()
> {
> m = 0; // error
> f (); // error
> n = 0; // ::n is modified
> g (); // ::g is called
The standard defines dependent names in 14.6.2 . AFAICT, none of
these qualify as dependent names.
> }
> };
>
>
> You must make the names dependent by prefixing them with this->. Here is the
> corrected definition of C<T>::g,
>
> template <typename T> void C<T>::g ()
> {
> this->m = 0;
> this->f ();
> this->n = 0
> this->g ();
> }
[snip]
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]