about the template pragramming

S

shuisheng

Dear All,

Assume I have a class template of multi-dimension point as follows:

template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

private:
double m_coordinate[nDim];
};

But for different dimetion points, their constructor are different such
as
Point<1>(double);
Point<2>(double, double);
Point<3>(double, double, double);

So we can specialize the classes to implement the constructors. But
this way need to rewrite the common code such as "double
GetCoordinate(int)". Is there any easy way to implement them? What I
mean is that just specializing those constructors rather than
specialize the total class.

Thanks for your help!

Shuisheng
 
K

Kai-Uwe Bux

shuisheng said:
Dear All,

Assume I have a class template of multi-dimension point as follows:

template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

private:
double m_coordinate[nDim];
};

But for different dimetion points, their constructor are different such
as
Point<1>(double);
Point<2>(double, double);
Point<3>(double, double, double);

So we can specialize the classes to implement the constructors. But
this way need to rewrite the common code such as "double
GetCoordinate(int)". Is there any easy way to implement them? What I
mean is that just specializing those constructors rather than
specialize the total class.

What about inheriting from an underlying struct/class that just manages the
common parts:

template < typename ValueType, unsigned int Dim >
class point_storate_policy {

ValueType data [ Dim ];

public:

static unsigned int const size = Dim;

typedef ValueType value_type;
typedef value_type * pointer;
typedef value_type & reference;

pointer begin ( void ) {
return data;
}

pointer end ( void ) {
return data + size;
}

reference operator[] ( unsigned int i ) {
return ( data );
}

};

template < unsigned int Dim >
class point;

template <>
struct point<1> : public point_storate_policy< double, 1 > {

point( double x ) {
(*this)[0] = x;
}

};

template <>
struct point<2> : public point_storate_policy< double, 2 > {

point( double x, double y ) {
(*this)[0] = x;
(*this)[1] = y;
}

};

#include <iostream>

int main ( void ) {
point<2> p ( 0.1, 0.4 );
std::cout << p[0] << " " << p[1] << '\n';
}


Best

Kai-Uwe Bux
 
G

Gianni Mariani

shuisheng said:
Dear All,

Assume I have a class template of multi-dimension point as follows:

template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

private:
double m_coordinate[nDim];
};

But for different dimetion points, their constructor are different such
as
Point<1>(double);
Point<2>(double, double);
Point<3>(double, double, double);

So we can specialize the classes to implement the constructors. But
this way need to rewrite the common code such as "double
GetCoordinate(int)". Is there any easy way to implement them? What I
mean is that just specializing those constructors rather than
specialize the total class.

Thanks for your help!


If you really really want to do this, you can use a feature of the
template function instantiation that allows you to specialize the
constructor.

// This template will have an error if L1 & L2 are not equal
template <int L1, int L2 >
struct AssertEqual
{
char foo[ (L1==L2)?1:-1 ]; // error if L1 != L2
};


template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

// define all the constuctors adding a default last parameter
// whose type will have an error if it is instantiated
Point( double v0, AssertEqual<nDim,1> & = AssertEqual<nDim,1>() )
{
m_coordinate[0] = v0;
}

Point( double v0, double v1, AssertEqual<nDim,2> & =
AssertEqual<nDim,2>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
}

Point( double v0, double v1, double v2, AssertEqual<nDim,3> & =
AssertEqual<nDim,3>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
m_coordinate[2] = v2;
}

private:
double m_coordinate[nDim];
};


Point<3> x3(1,2,3);
//Point<3> x2AssertEqual(1,2); // compile time error
Point<2> x2(1,2);
Point<1> x1(1);
 
S

shuisheng

Thank you for your good answer. I am just wondering where I put the
private member varaibels? In the base class or the individuan derived
class? Thanks.
 
S

shuisheng

You idea is so nice. I just still have a question:

What does "AssertEqual<nDim,1> & = AssertEqual<nDim,1>() " mean?
AssertEqual<nDim,1>() is an object. And AssertEqual<nDim,1> is a
class.
What is Class & = Object?

Thanks.


Gianni said:
shuisheng said:
Dear All,

Assume I have a class template of multi-dimension point as follows:

template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

private:
double m_coordinate[nDim];
};

But for different dimetion points, their constructor are different such
as
Point<1>(double);
Point<2>(double, double);
Point<3>(double, double, double);

So we can specialize the classes to implement the constructors. But
this way need to rewrite the common code such as "double
GetCoordinate(int)". Is there any easy way to implement them? What I
mean is that just specializing those constructors rather than
specialize the total class.

Thanks for your help!


If you really really want to do this, you can use a feature of the
template function instantiation that allows you to specialize the
constructor.

// This template will have an error if L1 & L2 are not equal
template <int L1, int L2 >
struct AssertEqual
{
char foo[ (L1==L2)?1:-1 ]; // error if L1 != L2
};


template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

// define all the constuctors adding a default last parameter
// whose type will have an error if it is instantiated
Point( double v0, AssertEqual<nDim,1> & = AssertEqual<nDim,1>() )
{
m_coordinate[0] = v0;
}

Point( double v0, double v1, AssertEqual<nDim,2> & =
AssertEqual<nDim,2>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
}

Point( double v0, double v1, double v2, AssertEqual<nDim,3> & =
AssertEqual<nDim,3>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
m_coordinate[2] = v2;
}

private:
double m_coordinate[nDim];
};


Point<3> x3(1,2,3);
//Point<3> x2AssertEqual(1,2); // compile time error
Point<2> x2(1,2);
Point<1> x1(1);
 
S

shuisheng

At last, I see your point. SO NICE ! ! !

"AssertEqual<nDim,1> & = AssertEqual<nDim,1>()" is an argument with a
default value, right? I think I am still a c++ novice.
You idea is so nice. I just still have a question:

What does "AssertEqual<nDim,1> & = AssertEqual<nDim,1>() " mean?
AssertEqual<nDim,1>() is an object. And AssertEqual<nDim,1> is a
class.
What is Class & = Object?

Thanks.


Gianni said:
shuisheng said:
Dear All,

Assume I have a class template of multi-dimension point as follows:

template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

private:
double m_coordinate[nDim];
};

But for different dimetion points, their constructor are different such
as
Point<1>(double);
Point<2>(double, double);
Point<3>(double, double, double);

So we can specialize the classes to implement the constructors. But
this way need to rewrite the common code such as "double
GetCoordinate(int)". Is there any easy way to implement them? What I
mean is that just specializing those constructors rather than
specialize the total class.

Thanks for your help!


If you really really want to do this, you can use a feature of the
template function instantiation that allows you to specialize the
constructor.

// This template will have an error if L1 & L2 are not equal
template <int L1, int L2 >
struct AssertEqual
{
char foo[ (L1==L2)?1:-1 ]; // error if L1 != L2
};


template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

// define all the constuctors adding a default last parameter
// whose type will have an error if it is instantiated
Point( double v0, AssertEqual<nDim,1> & = AssertEqual<nDim,1>() )
{
m_coordinate[0] = v0;
}

Point( double v0, double v1, AssertEqual<nDim,2> & =
AssertEqual<nDim,2>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
}

Point( double v0, double v1, double v2, AssertEqual<nDim,3> & =
AssertEqual<nDim,3>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
m_coordinate[2] = v2;
}

private:
double m_coordinate[nDim];
};


Point<3> x3(1,2,3);
//Point<3> x2AssertEqual(1,2); // compile time error
Point<2> x2(1,2);
Point<1> x1(1);
 
G

Gianni Mariani

shuisheng said:
At last, I see your point. SO NICE ! ! !

"AssertEqual<nDim,1> & = AssertEqual<nDim,1>()" is an argument with a
default value, right? I think I am still a c++ novice.

Yes, correct.
You idea is so nice. I just still have a question:

What does "AssertEqual<nDim,1> & = AssertEqual<nDim,1>() " mean?
AssertEqual<nDim,1>() is an object. And AssertEqual<nDim,1> is a
class.
What is Class & = Object?

Thanks.


Gianni said:
shuisheng wrote:
Dear All,

Assume I have a class template of multi-dimension point as follows:

template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

private:
double m_coordinate[nDim];
};

But for different dimetion points, their constructor are different such
as
Point<1>(double);
Point<2>(double, double);
Point<3>(double, double, double);

So we can specialize the classes to implement the constructors. But
this way need to rewrite the common code such as "double
GetCoordinate(int)". Is there any easy way to implement them? What I
mean is that just specializing those constructors rather than
specialize the total class.

Thanks for your help!

If you really really want to do this, you can use a feature of the
template function instantiation that allows you to specialize the
constructor.

// This template will have an error if L1 & L2 are not equal
template <int L1, int L2 >
struct AssertEqual
{
char foo[ (L1==L2)?1:-1 ]; // error if L1 != L2
};


template<int nDim>
class Point
{
public:
double GetCoordinate(int iDim)
{
return m_coordinate[iDim];
}

// define all the constuctors adding a default last parameter
// whose type will have an error if it is instantiated
Point( double v0, AssertEqual<nDim,1> & = AssertEqual<nDim,1>() )
{
m_coordinate[0] = v0;
}

Point( double v0, double v1, AssertEqual<nDim,2> & =
AssertEqual<nDim,2>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
}

Point( double v0, double v1, double v2, AssertEqual<nDim,3> & =
AssertEqual<nDim,3>() )
{
m_coordinate[0] = v0;
m_coordinate[1] = v1;
m_coordinate[2] = v2;
}

private:
double m_coordinate[nDim];
};


Point<3> x3(1,2,3);
//Point<3> x2AssertEqual(1,2); // compile time error
Point<2> x2(1,2);
Point<1> x1(1);
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,970
Messages
2,570,162
Members
46,710
Latest member
bernietqt

Latest Threads

Top