Template specialization for templated and primitive type template parameters

C

case2005

Can anyone help with the following, I don't know if it's possible, but I'm
certain there must be a standard way of dealing with this.

I have the following:

template<typename FooBar, typename Foo>
class Bar {

private:
Foo foo;
}

Now I want to be able to handle when 'Foo' is a primitive type, or more
specifically a primitive pointer type, like 'char *' and also when Foo is
itself a template class:

template<typename FooBar, template<T> class Foo>
class Bar {

private:
Foo<FooBar> foo;
}

All the member functions and other fields of Bar are common to both
template classes. Can I do this with template specialization, if so how, I
don't quite get it.

I also tried to achieve this with the following, which isn't ideal,
because the client of the template must be aware that primitive types
must be wrapped in 'PrimitiveType':

template<class T>
struct PrimitiveType
{
typedef T Type;
};

template<class T>
class WrappedClass
{
public:
typedef WrappedClass<T> Type;

private:
};

template<class FooBar, template<class T> class Foo>
class Bar {
public:

Foo<FooBar>::Type wibble;
};

In theory, 'Bar' can have it's template parameter 'Foo' specified as
either 'PrimitiveType' or 'WrappedClass'.

Alas compilation with g++ simply gives me:

error: syntax error before `;' token

for the line Foo<FooBar>::Type wibble;

I greatly appreciate any light shed on either of these issues.

Many thanks
 
N

Nicolas Pavlidis

case2005 said:
Can anyone help with the following, I don't know if it's possible, but I'm
certain there must be a standard way of dealing with this.

I have the following:

template<typename FooBar, typename Foo>
class Bar {

private:
Foo foo;
}

Now I want to be able to handle when 'Foo' is a primitive type, or more
specifically a primitive pointer type, like 'char *' and also when Foo is
itself a template class:

To find out if it is a pointer type you can do the following:

template< typename FooBar>
class Bar<FooBar, Foo*>
{
//......
};

If foo is some pointertype hte copiler will instanciate this
specialiization.
template<typename FooBar, template<T> class Foo>
class Bar {

private:
Foo<FooBar> foo;
}

All the member functions and other fields of Bar are common to both
template classes. Can I do this with template specialization, if so how, I
don't quite get it.

Maybe I got you wrong, but I think that's not necessary, because the
template will be instaciated with a concrete type, build by a template,
such as:

Bar<int, vector<double> >

for example. SO there is no such specialization necessary, IMHO.

I also tried to achieve this with the following, which isn't ideal,
because the client of the template must be aware that primitive types
must be wrapped in 'PrimitiveType':

template<class T>
struct PrimitiveType
{
typedef T Type;
};

template<class T>
class WrappedClass
{
public:
typedef WrappedClass<T> Type;

private:
};

template<class FooBar, template<class T> class Foo>
class Bar {
public:

Foo<FooBar>::Type wibble;
};

Here is

typename Foo<FooBar>::Type wibble

I greatly appreciate any light shed on either of these issues.

I think what you are searchig for are so called typetraits:

http://www.boost.org/libs/type_traits/index.html

This library work with a lot of differnet compilers.

If you use it you can ask the compiler if a special type is a primitive
type, or not and so on, and you'd have not to write a lot of template
specializations for each type.

HTH && Kind regards,
Nicolas
 
C

case2005

Nicolas

Thanks for this:
typename Foo<FooBar>::Type wibble

That worked. However, I don't understand:
To find out if it is a pointer type you can do
the following:
template< typename FooBar>
class Bar<FooBar, Foo*>
{
//......
};

What is Foo here? I get a parse error:

error: parse error before `>' token for:

class Bar<FooBar, Foo*>

Even if this does work, it's doen't give me the polymorphism I'm looking
for in the second template argument for a primitive pointer type template
argument or a templated class as the template argument.
Maybe I got you wrong, but I think that's not
necessary, because the template will be
instaciated with a concrete type, build by a
template, such as:

Bar<int, vector<double> >

for example. SO there is no such specialization > necessary, IMHO.

No, 'Bar' accepts 'Foo' without T specified, notice that T is passed by
field 'foo' as 'FooBar'
So for example I might pass 'WrappedClass':

to

template<typename FooBar, template<T> class Foo>
class Bar {

private:
Foo<FooBar> foo;
}

by

Bar<char, WrappedClass> bar;
bar.foo is then of type 'WrappedClass<char>' yes?

I think what you've missed is that I want 'Bar' to
accept both a primitive pointer like 'char *' in it's second template
argument and also a templated class template argument. Do you follow?

Kind regards
 
N

Nicolas Pavlidis

case2005 said:
Nicolas

Thanks for this:




That worked. However, I don't understand:




What is Foo here? I get a parse error:

Sory, I should look like this:
template<typename FooBar, typename Foo>
class Bar<FooBar, Foo*>
{
//.....
};

This should compile.
error: parse error before `>' token for:

class Bar<FooBar, Foo*>

Even if this does work, it's doen't give me the polymorphism I'm looking
for in the second template argument for a primitive pointer type template
argument or a templated class as the template argument.

So for example I might pass 'WrappedClass':

to

template<typename FooBar, template<T> class Foo>
class Bar {

private:
Foo<FooBar> foo;
}

by

Bar<char, WrappedClass> bar;
bar.foo is then of type 'WrappedClass<char>' yes?
Ok.

I think what you've missed is that I want 'Bar' to
accept both a primitive pointer like 'char *' in it's second template
argument and also a templated class template argument. Do you follow?

Yes. I'm not sure, but I think that this will not work, and you'd have
to pass the hole type such as PrimitiveTypeWrapper<SomeType> to the
template, I don;t really think that specializations to template template
arguments are working.

To solve yout Problem with the pointers to primitive types:

You can specializie to each type, such as int* double* and so on, or use
the type traits, to find out the charactaristics of the type, and
produce code accroding to the results.


HTH
Nicolas
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,731
Messages
2,569,432
Members
44,832
Latest member
GlennSmall

Latest Threads

Top