P: n/a

Dear All,
Assume I have a class template of multidimension 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  
Share this Question
P: n/a

shuisheng wrote:
Dear All,
Assume I have a class template of multidimension 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
KaiUwe Bux  
P: n/a

shuisheng wrote:
Dear All,
Assume I have a class template of multidimension 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);  
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.  
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 multidimension 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);
 
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 multidimension 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);
 
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 multidimension 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);
  This discussion thread is closed Replies have been disabled for this discussion.   Question stats  viewed: 1024
 replies: 6
 date asked: Sep 21 '06
