Click to See Complete Forum and Search --> : template and forward declaration
jflegert
October 3rd, 2002, 01:41 PM
I would like to do a forward declare of a nested class in a template, but can't get the syntax right. For example:
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
Yves M
October 3rd, 2002, 02:52 PM
Well, putting everything into a cpp file works (VC6) and putting everything into an h file works as well.
What error do you get ?
jflegert
October 3rd, 2002, 03:27 PM
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.
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.
Yves M
October 3rd, 2002, 03:51 PM
True.
I wonder whether the compiler implements this though. It might not be a lack of correct syntax...
Let's wait for the gurus ;)
Paul McKenzie
October 3rd, 2002, 03:53 PM
This compiles cleanly on Comeau and C++ Builder 6.0.
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
Yves M
October 3rd, 2002, 04:07 PM
Didn't have to wait for long :D Thanks Paul :)
ncf
October 3rd, 2002, 04:10 PM
Originally posted by jflegert
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:
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:
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.
kakalake
October 3rd, 2002, 07:06 PM
I tried this and it works...
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;
}
jflegert
October 4th, 2002, 07:06 AM
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.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.