template specialization

D

Denis Remezov

Rob said:
nsgi_2004 wrote in in
comp.lang.c++:


No a specialization is a completly new (and seperate) class,
here are three options:

1) Refactor your code in to a common base class say VectorBase:

template < typename T, int n >
class Vector : VectorBase< T, n >
{
// constructors and operator = () as required.
};

template <>
class Vector< float, 3 > : VectorBase< float, 3 >
{
// constructors and operator = () as required.

public:
Vector<float,3> cross_product(Vector<float, 3>& rhs)
{
return *this; // Cross product goes here.
}
};

2) Put the declaration of cross_product in Vector, but only
provide a defenition for the desired specialization:

template <>
Vector<float,3> Vector<float,3>::cross_product(Vector<float, 3>& rhs)
{
return *this;
}

Unfortunatly if this is called on an incorrect type you only get
a linker error, which are generaly rubbish (no line number etc).

3) Just implement cross_product in the (unspecialized) Vector.


4) Provide a partial specialisation of the class template for n=3
(using the definitions of #1):

template <typename T>
class Vector<T, 3> : public VectorBase<T, 3> {
public:
//...

const Vector cross_product(Vector const& rhs);
};

template <typename T>
const Vector<T, 3> Vector<T, 3>::cross_product(Vector const& rhs) {
return *this; // Cross product goes here.
}


Number 3 would be my default choice until I had found a good cause for a
specialisation (e.g. optimisation).

Denis
 
N

nsgi_2004

When you make a specialized class, does it "inherit" everything from the
general version as well. Essentially, I just need to add one function to a
special instance. Here is a small version of the code:

template <typename T, int n>
class Vector
{
public:
Vector<T, n> add(Vector<T, n>& rhs)
{
Vector<T, n> temp;
for(int i = 0; i < n; ++i)
temp.v = v + rhs.v;
return temp;
}

void print()
{
cout << "< ";
for(int i = 0; i < n; ++i)
cout << v << " ";
cout << ">" << endl;
}

T v[n];
};

// Define Specialization
template <>
class Vector<float, 3>
{
public:
Vector<float,3> cross_product(Vector<float, 3>& rhs)
{
return *this; // Cross product goes here.
}
};


I get the error "error C2039: 'v' : is not a member of 'Vector<T,n>'
with
[
T=float,
n=3
]"

It might be that my compiler does not support template specialization.
 
R

Rob Williscroft

nsgi_2004 wrote in in
comp.lang.c++:
When you make a specialized class, does it "inherit" everything from
the general version as well. Essentially, I just need to add one
function to a special instance. Here is a small version of the code:

No a specialization is a completly new (and seperate) class,
here are three options:

1) Refactor your code in to a common base class say VectorBase:

template < typename T, int n >
class Vector : VectorBase< T, n >
{
// constructors and operator = () as required.
};

template <>
class Vector< float, 3 > : VectorBase< float, 3 >
{
// constructors and operator = () as required.

public:
Vector<float,3> cross_product(Vector<float, 3>& rhs)
{
return *this; // Cross product goes here.
}
};



2) Put the declaration of cross_product in Vector, but only
provide a defenition for the desired specialization:

template <>
Vector<float,3> Vector<float,3>::cross_product(Vector<float, 3>& rhs)
{
return *this;
}

Unfortunatly if this is called on an incorrect type you only get
a linker error, which are generaly rubbish (no line number etc).

3) Just implement cross_product in the (unspecialized) Vector.


HTH.

Rob.
 
J

John Carson

nsgi_2004 said:
When you make a specialized class, does it "inherit" everything from
the general version as well.

No, it doesn't inherit anything.
Essentially, I just need to add one
function to a special instance. Here is a small version of the code:

template <typename T, int n>
class Vector
{
public:
Vector<T, n> add(Vector<T, n>& rhs)
{
Vector<T, n> temp;
for(int i = 0; i < n; ++i)
temp.v = v + rhs.v;
return temp;
}

void print()
{
cout << "< ";
for(int i = 0; i < n; ++i)
cout << v << " ";
cout << ">" << endl;
}

T v[n];
};

// Define Specialization
template <>
class Vector<float, 3>
{
public:
Vector<float,3> cross_product(Vector<float, 3>& rhs)
{
return *this; // Cross product goes here.
}
};


I get the error "error C2039: 'v' : is not a member of 'Vector<T,n>'
with
[
T=float,
n=3
]"

It might be that my compiler does not support template specialization.



It helps greatly if you post code that actually gives the error you claim.
Presumably, your actual code is something like this:

// Define Specialization
template <>
class Vector<float, 3>
{
public:
Vector<float,3> cross_product(Vector<float, 3>& rhs)
{
float temp0=v[0], temp1=v[1];
v[0] = v[1]*rhs.v[2] - v[2]*rhs.v[1];
v[1] = v[2]*rhs.v[0] - temp0*rhs.v[2];
v[2] = temp0*rhs.v[1] - temp1*rhs.v[0];
return *this;
}
};

(I am not sure why you are returning by value rather than by reference, but
that is a separate issue. Returning by value would make sense if you were
returning a temporary variable rather than *this.)


You basically have two options (that I can think of):

1. Define the specialised class in its entirety.
2. Declare the cross_product function in the general class, but don't
define it (you could provide a definition, but there is no point). You can
then specialise just the function, rather than the whole class, for
<float,3>, e.g.,


template <typename T, int n>
class Vector
{
public:
// declare, don't define
Vector<T,n> cross_product(Vector<T, n>& rhs);

Vector<T, n> add(Vector<T, n>& rhs)
{
Vector<T, n> temp;
for(int i = 0; i < n; ++i)
temp.v = v + rhs.v;
return temp;
}
void print()
{
cout << "< ";
for(int i = 0; i < n; ++i)
cout << v << " ";
cout << ">" << endl;
}
T v[n];
};


// Define Specialization of function only
template <>
Vector<float, 3> Vector<float,3>::cross_product(Vector<float, 3>& rhs)
{
float temp0=v[0], temp1=v[1];
v[0] = v[1]*rhs.v[2] - v[2]*rhs.v[1];
v[1] = v[2]*rhs.v[0] - temp0*rhs.v[2];
v[2] = temp0*rhs.v[1] - temp1*rhs.v[0];
return *this;
}
 
C

Christian Jaeger

2) Put the declaration of cross_product in Vector, but only
provide a defenition for the desired specialization:

template <>
Vector<float,3> Vector<float,3>::cross_product(Vector<float, 3>& rhs)
{
return *this;
}

Unfortunatly if this is called on an incorrect type you only get
a linker error, which are generaly rubbish (no line number etc).

You could in addition "implement"

template<typename T, int n>
Vector<T,n> Vector<T,n>::cross_product(Vector<T, n> /*const*/ & rhs)
{
use cross_product only with Vector<float,3> !
}

to get a compile-time error.
 

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
474,170
Messages
2,570,925
Members
47,464
Latest member
Bobbylenly

Latest Threads

Top