c++/5413: g++ fails to understand class template's typedef
Wirawan Purwanto
wirawan@camelot.physics.wm.edu
Thu Jan 17 10:26:00 GMT 2002
The following reply was made to PR c++/5413; it has been noted by GNATS.
From: "Wirawan Purwanto" <wirawan@camelot.physics.wm.edu>
To: <gcc-gnats@gcc.gnu.org>,
<gcc-prs@gcc.gnu.org>,
<wirawan0@hotmail.com>,
<gcc-bugs@gcc.gnu.org>,
<nobody@gcc.gnu.org>
Cc:
Subject: Re: c++/5413: g++ fails to understand class template's typedef
Date: Thu, 17 Jan 2002 13:16:29 -0500
This is a multi-part message in MIME format.
------=_NextPart_000_0049_01C19F59.2CFA9550
Content-Type: text/plain;
charset="iso-8859-1"
Content-Transfer-Encoding: 7bit
Please see attachment. Hopefully the attachment is not stripped again.
xref:
http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&p
r=5413
------=_NextPart_000_0049_01C19F59.2CFA9550
Content-Type: application/octet-stream;
name="gcc-template-bug1.cpp"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
filename="gcc-template-bug1.cpp"
/*
Help GCC developer!
I found an annoying bug in g++ recently. A simplified test program is
attached. This file alone is enough to reproduce the error.
I have tested this program under the following compilers:
1. g++ 2.95.2, mingw32 distribution. Typing "g++ -v" returns:
Reading specs from =
e:\APPS\GCC2.95.2\BIN\..\lib\gcc-lib\mingw32\2.95.2\specs
gcc driver version 2.95.2 19991024 (release) executing gcc version =
2.95.2-mingw
snapshot 20010329
2. g++ 2.95.3-6, distributed in mingw32 version 1.1. Typing "g++ -v" =
returns:
Reading specs from =
c:/usr/gcc/bin/../lib/gcc-lib/mingw32/2.95.3-6/specs
gcc version 2.95.3-6 (mingw special)
3. g++ 2.95.3, in Mandrake Linux version . Typing "g++ -v" returns:
Reading specs from /usr/lib/gcc-lib/i586-mandrake-linux/2.95.3/specs
gcc version 2.95.3 19991030 (prerelease)
This error is related to the template feature in the compiler.
The error can be briefly desrcribed as follows:
Suppose we declare a class template called PARENT, and in this class we
make a typedef PARENT_type. Any type should work (I have tried arrays
and structs and ints).
Then we declare another class template, called CHILD, whose base class
is _another_ class template (given in the template parameter of CHILD).
Now we want to use the typedefs declared in the base class. For example,
here I typed:
typedef typename parent_template<payload_data>::PARENT_type =
CHILD_type1;
in the declaration of class CHILD. This is OK as long as we use
CHILD_type1 within the declaration of the class. But once we declare it
OUTSIDE the class declaration (i.e. in the definition of method
CHILD<parent_template>::this_is_refused(CHILD_type1 xx) <--+
|
below, the compiler complains (line number can vary, but it refers to |
the line containing { } after the statement above): -------------------+
gcc-template-bug1.cpp:100: `parent_template<payload_data>' is not a
class, struct, or union type
gcc-template-bug1.cpp:100: syntax error before `{'
The fact that parent_template<payload_data> is used as a base class
implies that parent_template<payload_data> must be a class. Why can't we
assume that here? BTW I have checked this testcase against Borland C++ =
5.5
and Compaq C++ (in Alpha machine), they don't complain about this. Also
ecgs 2.96 for linux-alpha does not complain--but AFAIK this version is
not supported.
Please help me! Is there any solution or patch to this problem? I would
appreciate if you cc: also your reply to my address below.
Wirawan
<wirawan0@hotmail.com>
*/
template <class Payload =3D int>
class PARENT
{
public:
// this is a custom typedef defined in the parent
typedef int PARENT_type;
// this is an "extra" payload that can be customized by the user
Payload Data;
};
// this is the custom payload, defined by the user
struct payload_data { int x; };
// now we use the PARENT class template to define the CHILD. But here
// the CHILD will have a _specific_ payload (don't ask why---I did =
employ
// this organization in my own program).
template <template <class e> class parent_template>
class CHILD: public parent_template<payload_data>
{
public:
// typedef typeof(typename =
parent_template<payload_data>::PARENT_type) CHILD_type1;
// typedef parent_template<payload_data> prnt;
// typedef typename prnt::PARENT_type CHILD_type1;
typedef typename parent_template<payload_data>::PARENT_type =
CHILD_type1;
typedef int CHILD_type2[4];
void this_is_fine(CHILD_type2 xx);
void this_is_refused(CHILD_type1 xx); // this is not regarded as =
error
};
template <template <class e> class parent_template>
void CHILD<parent_template>::this_is_fine(CHILD_type2 xx)
{ }
template <template <class e> class parent_template>
void CHILD<parent_template>::this_is_refused(CHILD_type1 xx)
{ } // ^ but above line is regarded as =
erroneous!
CHILD<PARENT> sistem;
int main()
{
CHILD<PARENT>::PARENT_type uu; // however, this is =
OK
PARENT<double>::PARENT_type xyz;
return 0;
}
------=_NextPart_000_0049_01C19F59.2CFA9550--
More information about the Gcc-prs
mailing list