CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9
  1. #1
    Join Date
    Jul 2002
    Location
    Connecticut, U.S.
    Posts
    275

    template and forward declaration

    I would like to do a forward declare of a nested class in a template, but can't get the syntax right. For example:
    Code:
    template <class T>
    class Y
    {
    public:
        class Z;
    
        Z *z;
    
        void foo();
    };
    
    template <class T>
    void Y<T>::foo()
    {
    }
    
    template <class T>
    class Y<T>::Z
    {
    public:
        int i;
    };
    The code is all in the same header.
    The foo part compiles ok, but I can't get the Z part.
    I am using VC7.

    Thank you,
    John Flegert

  2. #2
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Well, putting everything into a cpp file works (VC6) and putting everything into an h file works as well.

    What error do you get ?

  3. #3
    Join Date
    Jul 2002
    Location
    Connecticut, U.S.
    Posts
    275
    The message was:

    error C2065: 'T' : undeclared identifier

    on the line: "class Y<T>::Z"

    The code compiled OK on VC 6. But when I modified the code as follows, I get a compilation error in VC7 and VC6.

    Code:
    template <class T>
    class Y
    {
    public:
        class Z;
    
        Z *z;
    
        void foo();
    };
    
    template <class T>
    class Y<T>::Z
    {
    public:
        int i;
    
        Z() { i = 0; }
    };
    
    template <class T>
    void Y<T>::foo()
    {
        z = new Z;
    }
    In VC6 the message is:

    error C2512: 'Z' : no appropriate default constructor available

    on the line that has "z = new Z"

    and in VC7 the message is:

    error C2065: 'T' : undeclared identifier

    on the line "class Y<T>::Z".

    Thanks for the help.

  4. #4
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    True.

    I wonder whether the compiler implements this though. It might not be a lack of correct syntax...

    Let's wait for the gurus

  5. #5
    Join Date
    Apr 1999
    Posts
    27,449
    This compiles cleanly on Comeau and C++ Builder 6.0.
    Code:
    template <class T>
    class Y
    {
    public:
        class Z;
    
        Z *z;
    
        void foo();
    };
    
    template <class T>
    class Y<T>::Z
    {
    public:
        int i;
    
        Z() { i = 0; }
    };
    
    template <class T>
    void Y<T>::foo()
    {
        z = new Z;
    }
    
    int main()
    {
      Y<int> MyY;
      MyY.foo();
    }
    I would suspect this is another Microsoft compiler deficiency when it comes to templates.

    Regards,

    Paul McKenzie

  6. #6
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588
    Didn't have to wait for long Thanks Paul

  7. #7
    Join Date
    Oct 2001
    Location
    California
    Posts
    27
    Originally posted by jflegert

    Code:
    template <class T>
    class Y
    {
    public:
        class Z;
    
        Z *z;
    
        void foo();
    };
    
    template <class T>
    class Y<T>::Z
    {
    public:
        int i;
    
        Z() { i = 0; }
    };
    
    template <class T>
    void Y<T>::foo()
    {
        z = new Z;
    }
    Does this help? You declared Z as a template class but Y::z is a pointer to a Z without a template type specifier, as is the "new Z" call. How does the compiler know what kind of Z you want?

    This worked for me in VC6. In the header:

    Code:
    template <class T, class S>
    class Y
    {
    public:
        template <class S> class Z
        {
        public:
           int i;
           Z() {i=0;}
        };
    
        Z<S> *z;
    
        void foo();
    };
    
    template <class T, class S>
    void Y<T,S>::foo()
    {
        z = new Z<S>;
    }
    and then in a cpp i was able to say this:
    Code:
       Y<int, float> foo;
       foo.foo();
    is that what you want? I realise i didnt forward declare Z, but my brain has started hurting (and my build finished) :-) Templates are so much fun.

  8. #8
    Join Date
    May 2000
    Location
    Germany
    Posts
    369
    I tried this and it works...

    Code:
    class Z;
    
    template <class T>
    class Y
    {
    public:
        Z *z;
    
        void foo();
    };
    
    class Z
    {
    public:
        int i;
        Z() { i = 1; }
    };
    
    template <class T>
    void Y<T>::foo()
    {
        z = new Z();
    	cout << z->i;
    }
    
    int main(int argc, char* argv[])
    {
    	Y<int> test;
    	test.foo();
    
    	return 0;
    }

  9. #9
    Join Date
    Jul 2002
    Location
    Connecticut, U.S.
    Posts
    275
    Paul,

    Thank you for trying it on the Comeau compiler.

    kakalake,

    I wanted Z to be nested.

    ncf,

    From the original post, I wanted Z to be forward declared. In my original code, if I didn't forward declare Z, it would have compiled.

    Everyone,
    Thanks for the replies.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured