Sign in to follow this  
Misery

Function template problem

Recommended Posts

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

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
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