Topic: STL: Using an STL list<> as a static member


Author: "David A. Keller" <kellermd@bellsouth.net>
Date: 1998/09/19
Raw View
I wanted to make an STL list<CClass> a static member of class CClass.
The way I attempted to code this was as follows:

class CClass;
typedef list<CClass> CClassList;

class CClassList
{
    static CClassList m_lst;
};

But I get a compiler error saying that the template cannot use an
undefined class.

Does anyone know how to get around this?




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Robert C. Paulsen, Jr." <paulsen@ZAP.imailbox.com>
Date: 1998/09/19
Raw View
David A. Keller wrote:
>
> I wanted to make an STL list<CClass> a static member of class CClass.
> The way I attempted to code this was as follows:
>
> class CClass;
> typedef list<CClass> CClassList;
>
> class CClassList
> {
>     static CClassList m_lst;
> };
>
> But I get a compiler error saying that the template cannot use an
> undefined class.
>
> Does anyone know how to get around this?

By changing "class CClassList" to "class CClass" the above compiles OK
in Borland C++5.02 (with the additions shown below). I think this must
be what you mean anyway otherwise you are defining the class CClassList
twice.

But, with MSVC++6.0 I get an error like you get. A possible workaround
is to use a pointer to CClassList instead of an actual CClassList. The
following works OK for me in both MSVC++6.0 and BC++5.02:

> class CClass;
> typedef std::list<CClass> CClassList;
>
> class CClass
> {
>     static CClassList *m_lst; // BC++5.02 can use m_lst instead of *m_lst
> public:
>     bool operator==( const CClass& rhs ); // required for BC++5.02
>     bool operator<( const CClass& rhs ); // required for BC++5.02
> };

I suspect a bug in MSVC++.

--
Robert Paulsen                         http://paulsen.home.texas.net
If my return address contains "ZAP." please remove it. Sorry for the
inconvenience but the unsolicited email is getting out of control.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Matthew Adams <mwa_una@csi.com>
Date: 1998/09/21
Raw View
"David A. Keller" wrote:

> I wanted to make an STL list<CClass> a static member of class CClass.

Firstly, you are then attempting to redefine CClassList, which was originally
a list<CClass> (in your typedef) as a new type, with a CClassList member.
However, assuming that this was a typo, what you are trying to compile is as
follows:

class CClass;
typedef list<CClass> CClassList;

class CClass
{
public:
    CClass();
    ~CClass();
private:
    static CClassList m_lst;
};

The Microsoft compiler, unfortunately, cannot compile this kind of thing, as
it needs to resolve all its types for template declarations up front.  The
code, as you have written it, compiles correctly using the VisualAge C++ V4.0
compiler from IBM, which has a different  template instantiation scheme that
actually works most of the time.

One possible solution if you are stuck with VC++ is to change your list of
things, to a list of pointers to things, and manage the destruction of the
list contents within CClass.  It _can_ manage that!  Incidentally, I use VC++
at work for many Win32 projects, and coding with heavy use of templates/stl
causes innumerable Internal Compiler Errors, crashes, and incorrect code
generation, even with SP3.

Matthew Adams
Senior Architect, Life Science Resources Ltd.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Matt Austern <austern@sgi.com>
Date: 1998/09/22
Raw View
"David A. Keller" <kellermd@bellsouth.net> writes:

> I wanted to make an STL list<CClass> a static member of class CClass.
> The way I attempted to code this was as follows:
>
> class CClass;
> typedef list<CClass> CClassList;
>
> class CClassList
> {
>     static CClassList m_lst;
> };
>
> But I get a compiler error saying that the template cannot use an
> undefined class.
>
> Does anyone know how to get around this?

At the time you're declaring the list<CClass>, CClass is an incomplete
type.  (It has been declared, but not defined.)  According to the C++
standard (17.4.3.6, paragraph 2), you can't use an incomplete type as
a template argument when you're instantiating a C++ library template.

The standardization committee discussed this issue specifically.
Everyone on the committee agreed that it would be useful, and we came
up with several examples where it would be very nice to have STL
containers of incomplete types.  We even found that it worked,
sometimes, with some implementations.  We also found, though, that
there were some cases where it would be impossible for library
implementors to make it work unless we changed the library
specification in other ways.

In this case, you can solve the problem either by (1) defining CClass
before you try to use CClass as a template parameter; or (2) use a
list of CClass* instead of a list of CClass.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]