Top of document
©Copyright 1999 Rogue Wave Software

Using the Traits Technique

To implement a traits parameter for a class, you add it as an extra template parameter to your class. You then supply a class for this parameter that encapsulates all the specific operations. Usually that class is itself a template.

As an example, let's look at the matrix problem described above. By using the traits technique, when you want to add a new type to the matrix you simply specialize the traits class, not the entire matrix. You do no more work than you have to and retain the ability to use the matrix on any reasonable number.

Here's how the matrix traits template and specializations for long and int might look. The example also includes a skeleton of the matrix class that uses the traits template.

template <class Num>
 class matrix_traits
 {
   // traits functions and literals
 };
 template <class Num, class traits>
 class matrix
 {
   // matrix
 }
 
 class matrix_traits<long> 
 {
   // traits functions and literals specific to long
 };
 
 class matrix_traits<int>
 {
   // traits functions and literals specific to int
 };
 
 _ etc.
 
 matrix<int, matrix_traits<int> > int_matrix;
 matrix<long, matrix_traits<long> > long_matrix;
 

Of course you don't even have to specialize on matrix_traits. You just have to make sure you provide the interface that matrix expects from its traits template parameter.

Most of the time, the operations contained in a traits class will be static functions so that there's no need to actually instantiate a traits object.

The Standard Library uses this technique to give the string class maximum flexibility and efficiency across a wide range of types. The string traits class provides elementary operations on character arrays. In the simplest case, this means providing string a wstring with access to the 'C' library functions for skinny and wide characters, for example Strcpy and wcstrcpy.

See the string_char_traits reference entry for a complete description of the traits class.


Top of document