Topic: Nested template class definitions


Author: Robert DiFalco <difalco@primenet.com>
Date: 1995/12/31
Raw View
How do I define a nested class in a template? It seems to me that logic
could offer this:

   template <class Item>
   class List_
   {
      public:
         .
         .
         .
         class Iterator;
   };


   template <class Item>
   class List_<Item>::Iterator : public CollectionIterators_<Item>
   {
      .
      .
      .
   };

However, in Visual C++ 4.0, this produces the painfully ambiguous error
message "error C2988: unrecognizable template declaration/definition".

So, what gives? Is this an MSVC 4.0 problem, or am I use the incorrect
syntax for defining a nested class outside of the outer classes scope?

TIA,

Robert
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: 1996/01/01
Raw View
Robert DiFalco <difalco@primenet.com> writes:

>How do I define a nested class in a template?

You can define it either inline in the outer class declaration, or you
can just declare it in the outer class declaration and define it
later.  The latter method was allowed only relatively recently, and so
not all compilers support it yet.

>It seems to me that logic could offer this:
>
>   template <class Item>
>   class List_
>   {
>      public:
>         .
>         .
>         .
>         class Iterator;
>   };
>
>
>   template <class Item>
>   class List_<Item>::Iterator : public CollectionIterators_<Item>
>   {
>      .
>      .
>      .
>   };

Yep, that is exactly right.

>However, in Visual C++ 4.0, this produces the painfully ambiguous error
>message "error C2988: unrecognizable template declaration/definition".
>
>So, what gives? Is this an MSVC 4.0 problem, or am I use the incorrect
>syntax for defining a nested class outside of the outer classes scope?

It is an MSCV 4.0 problem.

As a work-around, try the following structure instead.

   template <class Item>
   class List_
   {
      public:
         .
         .
         .
         class Iterator {
  .
  .
  .
 };
   };

--
Fergus Henderson              WWW: http://www.cs.mu.oz.au/~fjh
fjh@cs.mu.oz.au               PGP: finger fjh@128.250.37.3
---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]





Author: Alan Griffiths <aGriffiths@ma.ccngroup.com>
Date: 1996/01/03
Raw View
I fear we're getting off topic, but there are a lot of programmers
that will be thinking that the language implemented by Microsoft bears
some relationship to the standard.

In fact MSVC4 has quite a few problems with nested classes
and templates (examples below).  (I don't think MS incorporated
anything more recent than mid '94 - certainly not the public review
draft ANSI produced.)

The public draft is also far from clear in some areas (e.g. tempates
and the interaction between namespace and templates).  In particular
I feel that the second example below should be valid (without the
MSVC fix), but finding clear statements justifying this is beyond me.


Example 1:

    #include <vector.h>

    #if defined(_MSC_VER) && (_MSC_VER <= 1000)
        template<class T> class Class_Value {
            public:
                Class_Value() {}
                Class_Value(const T& t) : v(t) {}

            private:
                T v;
         };
    #endif

    template<class T> class Class {
        public:

        #if !(defined(_MSC_VER) && (_MSC_VER <= 1000))
            class Value {
                public:
                    Value() {}
                    Value(const T& t) : v(t) {}

                private:
                    T v;
            };
        #else
            typedef ::Class_Value<T> Value;
        #endif

            Value f(const T& t) const { return t; }

        private:

            // MS resolves this with incorrect name binding
            // - see above conditionals
            vector<Value> array;
    };

    typedef  Class<int> IntClass;

    int main() {
        IntClass c;
        IntClass::Value v = c.f(0);
        return 0;
    }

Example 2:

    #include <vector.h>

    namespace MyNameSpace {
        template<class T> class Element {
            public: T t;
        };

        template<class T> class Container {
            public: vector<MyNameSpace::Element<T> > array;
        };
    }

    #if defined(_MSC_VER) && (_MSC_VER <= 1000)
        using MyNameSpace::Element<int>;
    #endif

    typedef MyNameSpace::Element<int>   MyIntElement;
    typedef MyNameSpace::Container<int> MyIntContainer;

    int main() {
        MyIntContainer collection;
        MyIntElement   e;
        e.t = 1;

        collection.array.push_back(e);

        return 0;
    }

--
Alan Griffiths               | Also editor of: The ISDF Newsletter
Senior Systems Consultant,   | (An Association of C and C++ Users publication)
CCN Group Limited.           | (ISDF editor  : isdf@octopull.demon.co.uk)
(agriffiths@ma.ccngroup.com) | (For ACCU see : http://bach.cis.temple.edu/accu)

---
[ comp.std.c++ is moderated.  Submission address: std-c++@ncar.ucar.edu.
  Contact address: std-c++-request@ncar.ucar.edu.  The moderation policy
  is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]