Sign in to follow this  
Misery

Function template problem

Recommended Posts

Misery    354

Hello,

 

The template class looks as follows:

template <class DATA_TYPE,class INT_TYPE>
class Matrix
{
 public:
  DATA_TYPE *data; //data container
  INT_TYPE Rows,Cols; //number of columns and rows
};

 

Let us consider a situation in which there are four template instantations.

 

typedef Matrix<float,unsigned int> FloatMatrix;
typedef Matrix<double,unsigned int> DoubleMatrix;
typedef Matrix<signed int,unsigned int>IntMatrix;
typedef Matrix<unsigned int,unsigned int>uIntMatrix;

I have a function that prints a matrix in the console window. It actually does exactly the same for Float- and DoubleMatrix classes and behaves identically for Int- and uIntMatrix classes. But it behaves differently for integer and real matrices.

My question is:Is there any better way for defining the display function instead of writing it four times? If I make one template, it will not work properly for real matrices or for int matrices.

 

template<class DATA_TYPE,class INT_TYPE>
Display(const Matrix<DATA_TYPE,INT_TYPE> &M)
{
 //do sth
}

If I make specializations then I will have four definitions:

 

template<class INT_TYPE>
Display(const Matrix<double,INT_TYPE> &M)
{
 //do sth
}

template<class INT_TYPE>
Display(const Matrix<float,INT_TYPE> &M)
{
 //do sth
}

template<class INT_TYPE>
Display(const Matrix<int,INT_TYPE> &M)
{
 //do sth
}

template<class INT_TYPE>
Display(const Matrix<unsigned int,INT_TYPE> &M)
{
 //do sth
}

Is there any better solution?

Thanks in advance for any suggestions.

Share this post


Link to post
Share on other sites
Brother Bob    10344

You can use std::enable_if, or the boost equivalent, to select specialization for different groups of types. For example, you can select integers and reals using something like this:

[code]template<typename T> void foo(T v, typename std::enable_if<std::numeric_limits<T>::is_integer>::type * = nullptr)
{
    std::cout << "integer" << std::endl;
}

template<typename T> void foo(T v, typename std::enable_if<!std::numeric_limits<T>::is_integer>::type * = nullptr)
{
    std::cout << "real" << std::endl;
}


int main()
{
    foo(1); // int
    foo((short)2); // short
    foo(3.0); // double
    foo(4.0f); // float
}[/code]

int and short calls the integer variant, float and double calls the real variant, and std::enable_if is used to include/exclude certain templates from the name resolution.

Share this post


Link to post
Share on other sites
iMalc    2466
Also, are the number of rows and cols really not known at compile-time? If they are known at compile time, then making them too template parameters could be a good idea.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this