Topic: Template specialization for trait classes


Author: John Hancock <jhancock+@IUS5.IUS.cs.cmu.edu>
Date: 1998/04/17
Raw View

Folks --

I've got a question on template specialization for trait classes.

Let's say I'm doing some numerical work in an algorithm in which
I'd like to convert built-in types to double (and other types to
comparable types). I can write a trait class like this where the
default-behavior is to have Type be double.

template <class T>
struct PrecisionType{
  typedef double Type;
};

Now let's say I have some function (let's ignore what it returns currently,
call it void):

template <class T>
void accumulate(Array<T> &arr){
  PrecisionType<T>::Type val = 0;
  for (int i=0;i<arr.size();++i)
 val += arr[i];
  //do something with val here
}

This works fine. Accumulation is done with a double.

Of course, in this case, I didn't even need the trait class PrecisionType.
I could have just declared val as double. But now let's say I want Array to
be able to hold other arrays. So val in function accumulate will itself be
an array that accumulates each of the array elements (assuming Array
defines the necessary operators). I'd like to be able to specialize
the PrecisionType trait class to work for this case.

I don't know what is the right syntax or if it's possible (I can't
get it to work on the SGI CC compiler v7.1), but I'd like to say something
like:

template <class T>
struct PrecisionType<Array<T> >{
  typedef Array<PrecisionType::Type<T> > Type;
};

Now my compiler complains that PrecisionType is already declared.
Obviously, it is. The idea of the code is that I'd like the function
"accumulate" to work for arrays that contain arrays (that may contain
more arrays, etc.). However, I can't see how to do this.

One could specialize PrecisionType for each datatype of Array
individually, i.e.

struct PrecisionType<Array<int> >{
  typedef Array<double> Type;
};

but this becomes unwieldy quickly, and the possibilities explode
if Array had another template argument, e.g.
template <class T, int N> Array

Can you specialize PrecisionType for an Array<T, N> to give
Array<PrecisionType<T>::Type, N>? This requires template recursion,
but I believe that is allowed in principle, right?

If so, how could you do this? Is there anything in the standard
that would allow something like this? Is there any other way
to make function "accumulate" behave the way I'd like without
the trait class?

Thanks,

John
--
--------------------------------------------------------------------------
     John A. Hancock, Robotics Institute, Carnegie Mellon University
        jhancock@ri.cmu.edu, http://www.ius.cs.cmu.edu/~jhancock/
    "He who laughs has not yet heard the bad news." -- Bertolt Brecht


[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]