Typedef specializations

A

Alan Woodland

Hi,

I don't think I can't do this directly with standard C++, I've tried all
the ways I could think of that make sense and then some. I was wondering
if someone had a genius idea how I could produce behavior, using
standard C++, akin to what I guess can be best called a "typedef
specializations".

I.e. this being the default:

template <typename _T> class Foo {
public:
typedef _T type;
};

but in some cases (say _T is int) I want type to be a typedef for double
instead of int.

I've found loads of info on typedef templates, but this isn't quite the
same issue.

Any thoughts?

Thanks,
Alan
 
E

Eduardo Grajeda

Alan Woodland escribió:
Hi,

I don't think I can't do this directly with standard C++, I've tried all
the ways I could think of that make sense and then some. I was wondering
if someone had a genius idea how I could produce behavior, using
standard C++, akin to what I guess can be best called a "typedef
specializations".

I.e. this being the default:

template <typename _T> class Foo {
public:
typedef _T type;
};

but in some cases (say _T is int) I want type to be a typedef for double
instead of int.

You could add an extra template to be used by typedef, as in:

template <typename _T, typename TDef = _T> class Foo
{
public:
typedef TDef type;
};

With this you only specify the extra template when you want the typedef
to be other than _T:

Foo<int, double> foo;

And you can keep using it like always like this:

Foo<char> foo;

- Eduardo Grajeda
 
I

Ian Collins

Alan said:
Hi,

I don't think I can't do this directly with standard C++, I've tried all
the ways I could think of that make sense and then some. I was wondering
if someone had a genius idea how I could produce behavior, using
standard C++, akin to what I guess can be best called a "typedef
specializations".

I.e. this being the default:

template <typename _T> class Foo {

_T probably isn't a good idea.
public:
typedef _T type;
};

but in some cases (say _T is int) I want type to be a typedef for double
instead of int.

I've found loads of info on typedef templates, but this isn't quite the
same issue.

Any thoughts?
Which typedef are you referring to, the one inside the template?

something like

template <typename T, typename T1 = T> class Foo {
public:
typedef T1 type;
};

maybe?
 
M

Markus Schoder

Alan said:
Hi,

I don't think I can't do this directly with standard C++, I've tried all
the ways I could think of that make sense and then some. I was wondering
if someone had a genius idea how I could produce behavior, using
standard C++, akin to what I guess can be best called a "typedef
specializations".

I.e. this being the default:

template <typename _T> class Foo {
public:
typedef _T type;
};

but in some cases (say _T is int) I want type to be a typedef for double
instead of int.

I've found loads of info on typedef templates, but this isn't quite the
same issue.

Any thoughts?

Add the following to your header file:

template<> class Foo<int> {
public:
typedef double type;
};

This is called template specializiation if you want to google around.
 
M

mlimber

Alan said:
Hi,

I don't think I can't do this directly with standard C++, I've tried all
the ways I could think of that make sense and then some. I was wondering
if someone had a genius idea how I could produce behavior, using
standard C++, akin to what I guess can be best called a "typedef
specializations".

I.e. this being the default:

template <typename _T> class Foo {
public:
typedef _T type;
};

but in some cases (say _T is int) I want type to be a typedef for double
instead of int.

I've found loads of info on typedef templates, but this isn't quite the
same issue.

Any thoughts?

First things first: don't use _T. All identifiers starting with an
underscore and a capital letter are reserved for any use by the
implementation. Just use T.

To answer your question: You can specialize the whole class for int:

template<> class Foo<int>
{
typedef double type;
};

Alternately, you could use some template trickery such as Loki::Select
and Loki::IsSameType (see http://sourceforge.net/projects/loki-lib/) or
Boost.TypeTraits in conjunction with Boost.MPL (see
http://boost.org/libs/mpl/doc/refmanual/if.html and
http://boost.org/doc/html/boost_typetraits/reference.html#boost_typetraits.is_same
or
http://boost.org/doc/html/boost_typetraits/reference.html#boost_typetraits.is_integral).

It would look something like:

template <typename T>
struct Foo
{
typedef typename Loki::Select
<
Loki::IsSameType said:
>::Result type;
};

If you're going to be doing this for multiple types (e.g., int/double,
short/float, char/int), there may be some ways to simplify it using
typelists.

Cheers! --M
 
E

Eduardo Grajeda

Markus Schoder escribió:
Add the following to your header file:

template<> class Foo<int> {
public:
typedef double type;
};

This is called template specializiation if you want to google around.

However, if your is more than just the typedef, things might get
complicated when specializing, consider this:

template <typename T> class Foo {
public:
typedef T type;

void shake() { }
void dance() { }
};

If you want your specialized class to be the same, you'll have to
rewrite the methods on the specialized class:

template <> class Foo<int> {
public:
typedef double type;

void shake() { }
void dance() { }
};

To avoid this derive Foo from a base class that takes care of the
typedef, like this:

template <typename T> struct Base { // struct to avoid public:
typedef T type;
};

template <> struct Base<int> {
typedef double type;
};

template <typename T> class Foo : public Base<T> {
public:
void shake() { }
void dance() { }
};

Repeating only the typedef is way less complicated than the entire
content of the class.

- Eduardo Grajeda
 

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

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top