views:

231

answers:

1

Often when working with templates, you end up with something like:

template <T>
class the_class
{
public:
   // types
   typedef T value_type;
   typedef const value_type const_value_type;

   typedef value_type& reference;
   typedef const_value_type& const_reference;

   typedef value_type* pointer;
   typedef const_value_type* const_pointer;

   ...
};

This is lot's of the same stuff, though, copied to lots of different templated classes. Is it worthwhile to create something like:

// template_types.h

#define TEMPLATE_TYPES(T) \
       typedef T value_type; \
       typedef const value_type const_value_type; \
       typedef value_type& reference; \
       typedef const_value_type& const_reference; \
       typedef value_type* pointer; \
       typedef const_value_type* const_pointer;

So my class just becomes:

#include "template_types.h"

template <typename T>
class the_class
{
public:
   TEMPLATE_TYPES(T)
   ...
};

This seems cleaner, and avoids duplication when I make other template classes. Is this a good thing? Or should I avoid this and just copy-paste typedefs?

+11  A: 

Sure, what you're doing would work, but it's kind of old-school. Have you tried to put that stuff into another template class that you could derive from?

template <typename T>
class template_defs
{
public:
   // types
   typedef T value_type;
   typedef const value_type const_value_type;
   typedef value_type& reference;
   typedef const_value_type& const_reference;
   typedef value_type* pointer;
   typedef const_value_type* const_pointer;
};

template <typename T>
class the_class : public template_defs<T>
...
Mark Ransom
Thanks, I didn't even think of that.
Bruce
+1 This is also the reason why to inherit functors from unary and binary function. I actually had a related question, how one would **use** those typedefs in the_class (supposing they are obtained through some metaprogramming voodoo) but from http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18 it appears there's no *meaningful* way...
UncleBens
-1 from me. I disagree with this solution due to the "names not found in a dependent base class" issue. Every reference to to one of these members has to be qualified as follows: "typename template_defs<T>::". For example if you want to refer to "const_reference", you'd have to say "typename template_defs<T>::const_reference" which isn't really much better. A solution that mixes the macro version with the template however, might be OK.
Richard Corden
Actually, my downvote won't be registered. I previously voted followed by undo, and apparently that still starts the "vote locking timer" so I am unable to re-cast my vote. I must admit that there are some features of the SO site that really confuse me, and in case anybody is interested this /is/ by design: http://meta.stackoverflow.com/questions/18360/vote-too-old-to-be-changed-but-i-havent-voted
Richard Corden
UncleBens