 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
chokidar Guest
|
Posted: Fri Sep 24, 2004 3:43 pm Post subject: template template specialization |
|
|
Hello,
I get an error on Visual Studio 7.1 when I try to compile the
following code:
1 template <class T>
2 struct DerivedFrom {
3 typedef Nulltype Base;
4 };
5
6 template <template
7 struct DerivedFrom<Derived {
8 typedef Nulltype Base;
9 };
(7) : error C2065: 'T' : undeclared identifier
(9) : error C2953: 'DerivedFrom<Derived>' : template class has already
been defined
(9) : see declaration of 'DerivedFrom<Derived>'
(9) : error C2753: 'DerivedFrom<Derived>' : partial specialization
cannot match argument list for primary template
Basically, I want DerivedFrom to work for template classes as well as
regular classes. Is this even possible?
Thanks,
Hasan.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ben Hutchings Guest
|
Posted: Sat Sep 25, 2004 10:23 am Post subject: Re: template template specialization |
|
|
chokidar wrote:
| Quote: | Hello,
I get an error on Visual Studio 7.1 when I try to compile the
following code:
1 template <class T
2 struct DerivedFrom {
3 typedef Nulltype Base;
4 };
5
6 template
7 struct DerivedFrom<Derived {
8 typedef Nulltype Base;
9 };
(7) : error C2065: 'T' : undeclared identifier
(9) : error C2953: 'DerivedFrom<Derived>' : template class has already
been defined
(9) : see declaration of 'DerivedFrom<Derived>'
(9) : error C2753: 'DerivedFrom<Derived>' : partial specialization
cannot match argument list for primary template
|
I get an error message about Nulltype not being defined. ;-)
The important message is the first one: T is not declared. Yes,
there's a T in line 6, but that's a (redundant) name for the template
parameter of the "Derived" parameter and *not* a parameter of
DerivedFrom.
If you add a second parameter to DerivedFrom, typename T, then lines
6-9 will become a valid partial specialisation of DerivedFrom that
applies to specialisations of templates with a single template type
parameter.
| Quote: | Basically, I want DerivedFrom to work for template classes as well as
regular classes. Is this even possible?
|
That depends on whether you mean template classes (e.g.
std::vector<int>) or class templates (e.g. std::vector). Template
classes shouldn't need any special treatment. Class templates are a
completely different kind of entity, and can't be handled by the same
template. I don't see any way in the language to test whether a class
template is derived from any other class template, anyway, nor do I
see why that would be important.
--
Ben Hutchings
Reality is just a crutch for people who can't handle science fiction.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Sat Sep 25, 2004 10:30 am Post subject: Re: template template specialization |
|
|
[email]chokidar (AT) earthlink (DOT) net[/email] (chokidar) writes:
| Quote: | I get an error on Visual Studio 7.1 when I try to compile the
following code:
|
The compiler is correct.
| Quote: | 1 template <class T
2 struct DerivedFrom {
3 typedef Nulltype Base;
4 };
5
6 template
|
Note that in this line, T is just a formal parameter in Derived. This
template <template
is equivalent to your line 6.
Something like
template <typename T, template
should work if you want specializations of Derived to be treated differently
than other classes.
| Quote: | 7 struct DerivedFrom<Derived {
8 typedef Nulltype Base;
9 };
(7) : error C2065: 'T' : undeclared identifier
(9) : error C2953: 'DerivedFrom<Derived>' : template class has already
been defined
(9) : see declaration of 'DerivedFrom<Derived>'
(9) : error C2753: 'DerivedFrom<Derived>' : partial specialization
cannot match argument list for primary template
Basically, I want DerivedFrom to work for template classes as well as
regular classes. Is this even possible?
|
Maybe I don't understand the problem, but the primary template alone
should be sufficient for this.
Can you give a specialization example for each of the two cases to clarify
things?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Glen Low Guest
|
Posted: Sat Sep 25, 2004 6:00 pm Post subject: Re: template template specialization |
|
|
| Quote: | 6 template <template
7 struct DerivedFrom<Derived {
8 typedef Nulltype Base;
9 };
|
Try
template <template
struct DerivedFrom <Derived {
typedef Nulltype Base;
};
| Quote: | Basically, I want DerivedFrom to work for template classes as well as
regular classes. Is this even possible?
|
The above formulation means DerivedFrom is specialized for all
template classes with a single type param.
E.g.
class A { .. };
template <typename T> class B { .. };
template <typename T, typename U> class C { .. };
DerivedFrom <A> d0; // doesn't use above specialization
DerivedFrom <B d1; // uses above specialization
DerivedFrom <C d2; // doesn't use above specialization
Cheers,
Glen Low, Pixelglow Software
www.pixelglow.com
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alberto Barbati Guest
|
Posted: Sat Sep 25, 2004 6:00 pm Post subject: Re: template template specialization |
|
|
chokidar wrote:
| Quote: | Hello,
I get an error on Visual Studio 7.1 when I try to compile the
following code:
1 template <class T
2 struct DerivedFrom {
3 typedef Nulltype Base;
4 };
5
6 template
7 struct DerivedFrom<Derived {
8 typedef Nulltype Base;
9 };
|
The T in line 6 is used only to give a name to the template argument of
Derived and because of that it's completely ignored by the compiler.
That's exactly the same thing happening in function prototypes:
void foo(int a);
void foo(int bar);
void foo(int);
those are all valid prototypes of the same function. So your code can
also be written as:
template <template
struct DerivedFrom<Derived {
typedef Nulltype Base;
};
As you can see, T has been used without being previously declared and
the compiler rightly complains about that. But if you declare it first,
everything's ok:
template <typename T, template
struct DerivedFrom<Derived {
typedef Nulltype Base;
};
Hope it helps,
Alberto
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Dave B Guest
|
Posted: Sat Sep 25, 2004 6:35 pm Post subject: Re: template template specialization |
|
|
| Quote: | I get an error on Visual Studio 7.1 when I try to compile the
following code:
template <template
struct DerivedFrom<Derived {
typedef Nulltype Base;
};
|
T, as declared in your example as a parameter in a template template
parameter declaration, is not (and cannot be) used in the template
class definition (struct DerivedFrom<Derived). To
fix your problem, create another template parameter in the parameter
list of your specialization declaration to act as the argument when
using the template template parameter.
template
<
typename T, // <-- new parameter here
template
class Derived
| Quote: |
struct DerivedFrom { // Ok now! |
typedef Nulltype Base;
};
I suggest that you ommit parameter names in a template template
parameter list (as I did above...<typename>) to enforce the fact that
they are not used.
-dave
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
chokidar Guest
|
Posted: Sun Sep 26, 2004 9:39 am Post subject: Re: template template specialization |
|
|
So lets say I change the declarations to
// here's Nulltype
struct Nulltype {};
template <class T>
struct DerivedFrom {
typdef Nulltype Base;
};
template <template
struct DerivedFrom<Derived> {
typedef Nulltype Base;
};
And lets say we have this class hierarchy
class A {
static void foo();
};
template <>
struct DerivedFrom<B> {
typedef A Base;
};
class B : class A {
static void foo();
};
template <>
struct DerivedFrom<C> {
typedef B Base;
};
template <class T>
class C : class B {
static void foo();
};
I want to be able to write this kind of code:
template <class T>
void call_foo() {
T::foo();
call_foo<DerivedFrom();
}
template <>
void call_foo<Nulltype>() {
return;
}
int main() {
call_foo<C>();
return 0;
}
So to get this to work I need to get this to work:
template <class T>
class C : class B {
static void foo();
};
I hope this clarifies my problem. Thank you for the help.
Hasan.
Thomas Maeder <maeder (AT) glue (DOT) ch> wrote
| Quote: | chokidar (AT) earthlink (DOT) net (chokidar) writes:
I get an error on Visual Studio 7.1 when I try to compile the
following code:
The compiler is correct.
1 template <class T
2 struct DerivedFrom {
3 typedef Nulltype Base;
4 };
5
6 template
Note that in this line, T is just a formal parameter in Derived. This
template <template
is equivalent to your line 6.
Something like
template <typename T, template
should work if you want specializations of Derived to be treated differently
than other classes.
7 struct DerivedFrom<Derived {
8 typedef Nulltype Base;
9 };
(7) : error C2065: 'T' : undeclared identifier
(9) : error C2953: 'DerivedFrom<Derived>' : template class has already
been defined
(9) : see declaration of 'DerivedFrom<Derived>'
(9) : error C2753: 'DerivedFrom<Derived>' : partial specialization
cannot match argument list for primary template
Basically, I want DerivedFrom to work for template classes as well as
regular classes. Is this even possible?
Maybe I don't understand the problem, but the primary template alone
should be sufficient for this.
Can you give a specialization example for each of the two cases to clarify
things?
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Thomas Maeder Guest
|
Posted: Sun Sep 26, 2004 4:05 pm Post subject: Re: template template specialization |
|
|
[email]chokidar (AT) earthlink (DOT) net[/email] (chokidar) writes:
Please next time throw the code at a compiler before posting. There are
a bunch of errors in your code that a compiler would have caught.
| Quote: | So lets say I change the declarations to
// here's Nulltype
struct Nulltype {};
template <class T
struct DerivedFrom {
typdef Nulltype Base;
|
typedef Nulltype Base;
template <template
| Quote: | struct DerivedFrom<Derived> {
typedef Nulltype Base;
};
|
But this will not work.
DerivedFrom is a template whose parameter is a type. You can't specialize
it for a class template; a class template is not a type.
What you can do is something like
template <typename T, template
struct DerivedFrom< Derived {
typedef Nulltype Base;
};
| Quote: | And lets say we have this class hierarchy
class A {
static void foo();
|
foo is private. You won't be able to call it from call_foo().
| Quote: | };
template
struct DerivedFrom<B> {
typedef A Base;
};
class B : class A {
|
class B : public A {
| Quote: | static void foo();
|
foo is private. You won't be able to call it from call_foo().
The definition of B has to precede the specialization of DerivedFrom for B.
| Quote: | template
struct DerivedFrom<C> {
typedef B Base;
};
|
C is a template, as is DerivedFrom above. What about
template <typename T>
struct DerivedFrom< C {
typedef B Base;
};
| Quote: | template <class T
class C : class B {
|
class C : public B
| Quote: | static void foo();
|
foo is private. You won't be able to call it from call_foo().
The definition of C has to precede the specialization of DerivedFrom for
intances of C.
| Quote: | I want to be able to write this kind of code:
template
void call_foo() {
T::foo();
call_foo();
|
call_foo<typename DerivedFrom();
| Quote: | }
template
void call_foo<Nulltype>() {
return;
}
int main() {
call_foo<C>();
|
Which foo() should be called by call_foo() as a result of this call?
Again, call_foo is a function template whose template parameter is a type.
C is a template, though. This will not work.
To make the main() function compile, you can
* overload call_foo for templates like C
template <template
void call_foo()
{
}
I find it hard to figure out which foo() to call from there, though.
* instantiate call_foo on a specialization of C rather than C itself:
call_foo< C();
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|