 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
fabioppp Guest
|
Posted: Tue Dec 14, 2004 7:58 pm Post subject: Template specialization with partial types |
|
|
Consider this struct:
template <typename T>
struct TypeOf
{
// ...
};
I have many explicit specialization:
template<>
struct TypeOf<int>
{
//...
};
//...
and many partial specialization:
template <typename T>
struct TypeOf<T*>
{
//...
};
template <typename T>
struct TypeOf<std::vector
{
//...
};
//..
Now I'd like to have another special behavior for incomplete types, so
that i could write:
TypeOf< std::vector >::....
Is there some way to achieve this specialization?!
Now I've introduced another class (ContainerTypeOf), but I wanna use
just TypeOf class.
template <template
struct ContainerTypeOf<Container>
{
//...
};
--
Fabio.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Graeme Prentice Guest
|
Posted: Wed Dec 15, 2004 1:06 pm Post subject: Re: Template specialization with partial types |
|
|
On 14 Dec 2004 14:58:16 -0500, fabioppp wrote:
| Quote: | Consider this struct:
template <typename T
struct TypeOf
{
// ...
};
I have many explicit specialization:
|
[snip]
| Quote: |
Now I'd like to have another special behavior for incomplete types, so
that i could write:
TypeOf< std::vector >::....
Is there some way to achieve this specialization?!
Now I've introduced another class (ContainerTypeOf), but I wanna use
just TypeOf class.
template <template
struct ContainerTypeOf<Container
{
//...
};
|
I'm not sure I understand. In TypeOf< std::vector >::
std:vector is not an incomplete type - it's the name of a class
template. I assume you mean it's "incomplete" because it doesn't
specify the container element type e.g. vector<int> - incomplete type
is an official term defined in 3.9 para 6 (an incomplete class, array of
unknown size etc).
Assuming you mean that you want to be able to declare something like
TypeOf<int> object1;
TypeOf<std::vector> object2;
that isn't possible because C++ doesn't allow you to overload template
class definitions.
You can partially specialize TypeOf like this
template <
template < typename elem,
typename alloc = std::allocator
class Container, typename t3,typename t4 >
struct TypeOf<Container
{
//...
};
and this specialization will be used whenever the template argument is
type generated from a class template that takes two parameters - unless
there is a more specialised specialization - such as the one you had
for vector<T>
template <typename T>
struct TypeOf<std::vector{};
Function templates can be overloaded, so if foo was a template function
with appropriate overloads, you could write
foo<std::vector>();
and
foo<std::vector();
So if you don't mind writing TypeOf as a macro, you may be able to
achieve the result you want i.e.
TypeOf(std::vector)::result
or
TypeOf(std::vector<int>)::result
- or just leave off the ::result bit altogether
The macro could use overloaded template functions to distinguish between
an argument that is the name of a class template (e.g. std::vector) and
an argument that is a type (e.g. vector<int>) as in this code - note
the spaces around "y" in the macro.
#include <vector>
#include <typeinfo>
#include <iostream>
#include <ostream>
template <int x>
struct tx
{
typedef char size[x];
};
template <int x>
struct type_decode;
template <
template < typename elem,
typename alloc = std::allocator
class Container >
tx<1>::size & func();
template <>
struct type_decode<sizeof(tx<1>::size)>
{
typedef int result;
};
template < typename T >
tx<2>::size & func();
template <>
struct type_decode<sizeof(tx<2>::size)>
{
typedef char result;
};
#define TypeOf(y) type_decode< sizeof func< y >() >::result
int main()
{
TypeOf(std::vector) abc;
TypeOf(std::vector<int>) abc2;
std::cout << typeid( TypeOf(std::vector) ).name();
std::cout << typeid( TypeOf(std::vector
}
Graeme
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Tom Widmer Guest
|
Posted: Wed Dec 15, 2004 1:08 pm Post subject: Re: Template specialization with partial types |
|
|
On 14 Dec 2004 14:58:16 -0500, fabioppp <fabioppp_it (AT) yahoo (DOT) it> wrote:
| Quote: | Consider this struct:
template <typename T
struct TypeOf
{
// ...
};
I have many explicit specialization:
template
struct TypeOf
{
//...
};
//...
and many partial specialization:
template
struct TypeOf
{
//...
};
template
struct TypeOf
{
//...
};
//..
Now I'd like to have another special behavior for incomplete types, so
that i could write:
TypeOf< std::vector >::....
|
std::vector isn't an incomplete type or even a type of any kind - it's
a class template, e.g. a template for creating types.
| Quote: | Is there some way to achieve this specialization?!
|
No, since your TypeOf takes a type, which is a very different thing
from a template.
| Quote: | Now I've introduced another class (ContainerTypeOf), but I wanna use
just TypeOf class.
|
You should call it "TemplateContainerOf" or similar. Again, a class
template isn't a type.
| Quote: | template <template
struct ContainerTypeOf
{
//...
};
|
What is your usage such that you need a specialization for non-types?
What does your TypeOf template do?
Tom
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
fabioppp Guest
|
Posted: Wed Dec 15, 2004 4:48 pm Post subject: Re: Template specialization with partial types |
|
|
Tom Widmer wrote:
| Quote: | On 14 Dec 2004 14:58:16 -0500, fabioppp <fabioppp_it (AT) yahoo (DOT) it> wrote:
What is your usage such that you need a specialization for non-types?
What does your TypeOf template do?
|
To retrieve the descriptor of a type.
class metaclass {};
class A {
static metaclass _mc;
};
template <typename T>
struct TypeOf<T> {
static metaclass& get() { return T::_mc; }
};
I want to describe template class too, not just their instantiation
and I want to retrieve the metaclass of a template class through TypeOf.
--
Fabio.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
fabioppp Guest
|
Posted: Thu Dec 16, 2004 1:45 pm Post subject: Re: Template specialization with partial types |
|
|
Graeme Prentice wrote:
| Quote: | On 14 Dec 2004 14:58:16 -0500, fabioppp wrote:
...
|
Thanks a lot. I've done in this way:
#include <vector>
template <int id, class C, class C1, class C2>
struct Select;
template <class C, class C1, class C2>
struct Select<1,C,C1,C2> { typedef C Result; };
template <class C, class C1, class C2>
struct Select<2,C,C1,C2> { typedef C1 Result; };
template <class C, class C1, class C2>
struct Select<3,C,C1,C2> { typedef C2 Result; };
template <int id>
class SizeOfHelper
{
char dummy[id];
};
template <class T>
SizeOfHelper<1> func();
template <template
SizeOfHelper<2> func();
template <template
SizeOfHelper<3> func();
template <typename T>
struct TypeOf
{
static void get() {}
};
template <template
struct TypeOf1
{
static void get() {}
};
template <template
struct TypeOf2
{
static void get() {}
};
struct TypeOfInfo
{
template <class T>
static void get()
{
TypeOf<T>::get();
}
};
struct TypeOfInfo1
{
template <template
static void get()
{
TypeOf1<T>::get();
}
};
struct TypeOfInfo2
{
template <template
static void get()
{
TypeOf2<T>::get();
}
};
#define TYPEOF(Ty)
Select< sizeof(func
TypeOfInfo,
TypeOfInfo1,
TypeOfInfo2
| Quote: | ::Result::get<Ty>()
|
int main()
{
TYPEOF(std::vector);
TYPEOF(int);
return 0;
}
--
Fabio.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Graeme Prentice Guest
|
Posted: Fri Dec 17, 2004 5:33 pm Post subject: Re: Template specialization with partial types |
|
|
On 16 Dec 2004 08:45:50 -0500, fabioppp wrote:
[snip]
| Quote: |
template <int id
class SizeOfHelper
{
char dummy[id];
};
template
SizeOfHelper<1> func();
template <template
SizeOfHelper<2> func();
template <template
SizeOfHelper<3> func();
|
[snip]
| Quote: |
#define TYPEOF(Ty)
Select< sizeof(func
TypeOfInfo,
TypeOfInfo1,
TypeOfInfo2
::Result::get<Ty>()
|
This code would fail if the compiler added any packing bytes to the end
of SizeOfHelper struct which was why I used the size of the array
instead of the size of the struct.
Graeme
[ 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
|
|