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 <typename T> class Derived>
7 struct DerivedFrom<Derived<T> > {
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! ]
|
|
0
|
|
|
|
Reply
|
chokidar (2)
|
9/24/2004 3:43:35 PM |
|
chokidar wrote:
> 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 <typename T> class Derived>
> 7 struct DerivedFrom<Derived<T> > {
> 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.
> 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! ]
|
|
0
|
|
|
|
Reply
|
Ben
|
9/25/2004 10:23:30 AM
|
|
chokidar@earthlink.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 <template <typename T> class Derived>
Note that in this line, T is just a formal parameter in Derived. This
template <template <typename> class Derived>
is equivalent to your line 6.
Something like
template <typename T, template <typename> class Derived>
should work if you want specializations of Derived to be treated differently
than other classes.
> 7 struct DerivedFrom<Derived<T> > {
> 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! ]
|
|
0
|
|
|
|
Reply
|
Thomas
|
9/25/2004 10:30:43 AM
|
|
> 6 template <template <typename T> class Derived>
> 7 struct DerivedFrom<Derived<T> > {
> 8 typedef Nulltype Base;
> 9 };
Try
template <template <typename> class Derived, typename T>
struct DerivedFrom <Derived <T> > {
typedef Nulltype Base;
};
> 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 <int> > d1; // uses above specialization
DerivedFrom <C <int, char> > 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! ]
|
|
0
|
|
|
|
Reply
|
glenlow
|
9/25/2004 6:00:13 PM
|
|
chokidar wrote:
> 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 <typename T> class Derived>
> 7 struct DerivedFrom<Derived<T> > {
> 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 <typename> class Derived>
struct DerivedFrom<Derived<T> > {
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 <typename> class Derived>
struct DerivedFrom<Derived<T> > {
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! ]
|
|
0
|
|
|
|
Reply
|
Alberto
|
9/25/2004 6:00:58 PM
|
|
>I get an error on Visual Studio 7.1 when I try to compile the
>following code:
>template <template <typename T> class Derived>
>struct DerivedFrom<Derived<T> > {
> 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<T /*this is bad*/> >). 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 <typename> // <-- notice no 'T' here
class Derived
>
struct DerivedFrom<Derived<T> > { // 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! ]
|
|
0
|
|
|
|
Reply
|
Dave
|
9/25/2004 6:35:42 PM
|
|
So lets say I change the declarations to
// here's Nulltype :-)
struct Nulltype {};
template <class T>
struct DerivedFrom {
typdef Nulltype Base;
};
template <template <typename> Derived>
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<T>::Base>();
}
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@glue.ch> wrote in message news:<m2llezr5db.fsf@madbox2.local>...
> chokidar@earthlink.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 <template <typename T> class Derived>
>
> Note that in this line, T is just a formal parameter in Derived. This
>
> template <template <typename> class Derived>
>
> is equivalent to your line 6.
>
>
> Something like
>
> template <typename T, template <typename> class Derived>
>
> should work if you want specializations of Derived to be treated differently
> than other classes.
>
>
> > 7 struct DerivedFrom<Derived<T> > {
> > 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! ]
|
|
0
|
|
|
|
Reply
|
chokidar
|
9/26/2004 9:39:08 AM
|
|
chokidar@earthlink.net (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.
> 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 <typename> Derived>
template <template <typename> class Derived>
> 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 <typename> class Derived>
struct DerivedFrom< Derived<T> > {
typedef Nulltype Base;
};
> 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().
> };
>
> template <>
> struct DerivedFrom<B> {
> typedef A Base;
> };
>
> class B : class A {
class B : public A {
> 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.
> template <>
> struct DerivedFrom<C> {
> typedef B Base;
> };
C is a template, as is DerivedFrom above. What about
template <typename T>
struct DerivedFrom< C<T> > {
typedef B Base;
};
> template <class T>
> class C : class B {
class C : public B
> 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.
> I want to be able to write this kind of code:
>
> template <class T>
> void call_foo() {
> T::foo();
> call_foo<DerivedFrom<T>::Base>();
call_foo<typename DerivedFrom<T>::Base>();
> }
>
> 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?
> return 0;
> }
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 <typename> class T>
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<B> >();
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
0
|
|
|
|
Reply
|
Thomas
|
9/26/2004 4:05:50 PM
|
|
|
7 Replies
266 Views
(page loaded in 3.728 seconds)
Similiar Articles: template template specialization - comp.lang.c++.moderated ...Hello, I get an error on Visual Studio 7.1 when I try to compile the following code: 1 template 2 struct DerivedFrom { 3 typedef Nulltype Bas... How to suppress template specialization? - comp.lang.c++.moderated ...I need to use bool type of vectors in in a code based on STL and and MPI2 library routines. My straightforward attempt was to instantiate vector varia... explicit instantiation of a template can only occur at namespace ...template template specialization - comp.lang.c++.moderated ... explicit instantiation of a template can only occur at namespace ... template template specialization - comp ... how to find eye template... - comp.soft-sys.matlabcan any body tell me that how can i find eye template??? thanks in ... how to find eye template... - comp.soft-sys.matlab How to suppress template specialization ... U++ 2791 released - comp.lang.c++.moderated- In Vector and Array template classes, interface was changed so that all ... Partial specialization of a template member function 1 72 c_kernel (3) How to simulate variadic templates? - comp.lang.c++.moderated ...Hi all, With a current problem, I found the variadic templates in C++0x ... New( A1 a1, A2 a2, A3 a3, A4 a4) {/* factory */ } > > and then specializations i.e. > > template ... Non-member operator overloading, linker complains - comp.lang.c++ ...Problem is, that U don't specify body of friend Matrix<T, d, e> operator-( const Matrix<T, d, e>& m ). Try this code: template<typename T, unsigned int d, unsigned ... SOLUTION: compile time array size using type only - comp.lang.c++ ...Hi here is the way for finding array size using type only ///// template class cx_array_length { template static inline const char (&_boun... const member functions in classes derived from templates. - comp ...template template specialization - comp.lang.c++.moderated ... const member functions in classes derived from templates. - comp ... template template specialization - comp ... ANNOUNCE: A C++ Class Browser Sidekick for Vi, Vim, Emacs & Xemacs ...o Sirius digests template specialization constructs correctly, but may not process them correctly. o Using directives are digested, but not processed. Template Specialization and Partial Specialization in C++ ...How to use template specialization and partial specialization. ... Template Specialization In many cases when working with templates, you'll write one generic ... Template (C++) - Wikipedia, the free encyclopediaTemplates are a feature of the C++ programming language that allow functions and classes to operate with generic types. This allows a function or class to work on ... 7/23/2012 4:27:55 PM
|