By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
431,919 Members | 1,625 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 431,919 IT Pros & Developers. It's quick & easy.

about the template pragramming

P: n/a
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

Sep 21 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
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.
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[i] );
}

};

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<2p ( 0.1, 0.4 );
std::cout << p[0] << " " << p[1] << '\n';
}
Best

Kai-Uwe Bux
Sep 21 '06 #2

P: n/a
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<3x3(1,2,3);
//Point<3x2AssertEqual(1,2); // compile time error
Point<2x2(1,2);
Point<1x1(1);
Sep 21 '06 #3

P: n/a
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.

Sep 21 '06 #4

P: n/a
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,1is a
class.
What is Class & = Object?

Thanks.
Gianni Mariani wrote:
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<3x3(1,2,3);
//Point<3x2AssertEqual(1,2); // compile time error
Point<2x2(1,2);
Point<1x1(1);
Sep 21 '06 #5

P: n/a
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.

shuisheng wrote:
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,1is a
class.
What is Class & = Object?

Thanks.
Gianni Mariani wrote:
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<3x3(1,2,3);
//Point<3x2AssertEqual(1,2); // compile time error
Point<2x2(1,2);
Point<1x1(1);
Sep 21 '06 #6

P: n/a
shuisheng wrote:
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.
>
shuisheng wrote:
>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,1is a
class.
What is Class & = Object?

Thanks.
Gianni Mariani wrote:
>>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<3x3(1,2,3);
//Point<3x2AssertEqual(1,2); // compile time error
Point<2x2(1,2);
Point<1x1(1);
Sep 24 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.