Specialization errors

P

pmatos

Hi all,

I have implemented a matrix template to suit my needs and now I've
implemented some methods for computing SVD decomposition of
Matrix<double>.
I have:
template <class T>
class Matrix {
public:
....

Line 45: void svdcmp(Matrix<double> *u, vector<double> *wvec,
Matrix<double> *v);

....
};

Line 365: template <>
Line 366: void Matrix<double>::svdcmp(Matrix<double> *u, vector<double>
*wvec, Matrix<double> *v) {

....

}

I get the following error from gcc-3.3.4:
matrix.hpp:366: error: specialization of void
Matrix<T>::svdcmp(Matrix<double>*, std::vector<double,
std::allocator<double> >*, Matrix<double>*) [with T = double] after
instantiation
matrix.hpp:366: error: prototype for `void
Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]' does not match any in class `Matrix<double>'
matrix.hpp:45: error: candidate is: void
Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]
matrix.hpp:366: error: `void Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]' and `void Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double,
std::allocator<double> >*, Matrix<double>*) [with T = double]'
cannot be
overloaded

This messages can get scary... I can't get where the problem is. Any
ideas?

Cheers,

Paulo Matos
 
B

benben

pmatos said:
Hi all,

I have implemented a matrix template to suit my needs and now I've
implemented some methods for computing SVD decomposition of
Matrix<double>.
I have:
template <class T>
class Matrix {
public:
...

Line 45: void svdcmp(Matrix<double> *u, vector<double> *wvec,
Matrix<double> *v);

...
};

Line 365: template <>
Line 366: void Matrix<double>::svdcmp(Matrix<double> *u, vector<double>
*wvec, Matrix<double> *v) {


I think you mean:

template <typename T>
void Matrix<T>::svdcmp(
Matrix<double>* u, vector<double>*wvec, Matrix<double>* v)
{
// ...
}


OR:

template <>
class Matrix<double>
{
public:
void svdcmp(
Matrix* u, vector<double>* wvec, Matrix* v);
//...
};

void Matrix<double>::svdcmp(
Matrix<double>* u, vector<double>* wvec, Matrix<double>* v)
{
// ...
}


...

}

I get the following error from gcc-3.3.4:
matrix.hpp:366: error: specialization of void
Matrix<T>::svdcmp(Matrix<double>*, std::vector<double,
std::allocator<double> >*, Matrix<double>*) [with T = double] after
instantiation
matrix.hpp:366: error: prototype for `void
Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]' does not match any in class `Matrix<double>'
matrix.hpp:45: error: candidate is: void
Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]
matrix.hpp:366: error: `void Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]' and `void Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double,
std::allocator<double> >*, Matrix<double>*) [with T = double]'
cannot be
overloaded

This messages can get scary... I can't get where the problem is. Any
ideas?

Cheers,

Paulo Matos
 
P

pmatos

benben said:
I think you mean:

template <typename T>
void Matrix<T>::svdcmp(
Matrix<double>* u, vector<double>*wvec, Matrix<double>* v)
{
// ...
}

This will define svdcmp for all T of Matrix. Which should not be the
case. I can have a Matrix of anything but svdcmp should only work for
double.
OR:

template <>
class Matrix<double>
{
public:
void svdcmp(
Matrix* u, vector<double>* wvec, Matrix* v);
//...
};

void Matrix<double>::svdcmp(
Matrix<double>* u, vector<double>* wvec, Matrix<double>* v)
{
// ...
}

...

}

I get the following error from gcc-3.3.4:
matrix.hpp:366: error: specialization of void
Matrix<T>::svdcmp(Matrix<double>*, std::vector<double,
std::allocator<double> >*, Matrix<double>*) [with T = double] after
instantiation
matrix.hpp:366: error: prototype for `void
Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]' does not match any in class `Matrix<double>'
matrix.hpp:45: error: candidate is: void
Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]
matrix.hpp:366: error: `void Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double, std::allocator<double> >*, Matrix<double>*)
[with T =
double]' and `void Matrix<T>::svdcmp(Matrix<double>*,
std::vector<double,
std::allocator<double> >*, Matrix<double>*) [with T = double]'
cannot be
overloaded

This messages can get scary... I can't get where the problem is. Any
ideas?

Cheers,

Paulo Matos
 
P

pmatos

benben said:
template <>
class Matrix<double>
{
public:
void svdcmp(
Matrix* u, vector<double>* wvec, Matrix* v);
//...
};

void Matrix<double>::svdcmp(
Matrix<double>* u, vector<double>* wvec, Matrix<double>* v)
{
// ...
}

There's an issue with having:

template <class T>
class Matrix {
public:
void foo();
...
};

template<class T>
void Matrix<T>::foo() {
....
}

template <>
class Matrix<double> {
public:
void onlyfordouble();
};

void Matrix<double>::eek:nlyfordouble() {
// CAN'T ACCESS FOO
}

onlyfordouble() cannot access foo but it should be accessible since foo
is defined for all T, so should be defined for double too!
 
G

Greg

pmatos said:
There's an issue with having:

template <class T>
class Matrix {
public:
void foo();
...
};

template<class T>
void Matrix<T>::foo() {
...
}

template <>
class Matrix<double> {
public:
void onlyfordouble();
};

void Matrix<double>::eek:nlyfordouble() {
// CAN'T ACCESS FOO
}

onlyfordouble() cannot access foo but it should be accessible since foo
is defined for all T, so should be defined for double too!

Since you have specialized the Matrix template for the type double, the
Matrix<double> class will have only those members and methods declared
in the specialization. Matrix<double> does not "inherit" the routines
declared in the Matrix class template. If Matrix<double> should have a
foo method, it has to declare one.

It's also unclear whether a Matrix<double> specialization is even
needed. Matrix<T> already declares a svd routine that accepts only
Matrix<double> parameters. Does the Matrix object itself also need to
be a Matrix<double>? Even if it does, the svd routine in Matrix<T>
could be changed to accept Matrix<T> parameters. The instantiation of a
Matrix<double> would have then an svd method that would accept
Matrix<double> parameters without requiring specialization.

Greg
 
B

benben

pmatos said:
There's an issue with having:

template <class T>
class Matrix {
public:
void foo();
...
};

template<class T>
void Matrix<T>::foo() {
...
}

template <>
class Matrix<double> {
public:
void onlyfordouble();
};

void Matrix<double>::eek:nlyfordouble() {
// CAN'T ACCESS FOO
}

onlyfordouble() cannot access foo but it should be accessible since foo
is defined for all T, so should be defined for double too!

pmatos,

Even though Matrix<double> and Matrix<T> come from a single template, they
are ultimately two distinct types. One way to share common elements between
different types is to factor out the common elements to a base class
(template). E.g.

template <typename T>
class Matrix_base
{
public:
void foo(void);
};

template <typename T>
class Matrix: private Matrix_base<T>
{
public:
using Matrix_base::foo; // make foo available
// ...
};

template <>
class Matrix<double>: private Matrix_base<double>
{
public:
using Matrix_base::foo;
void onlyfordouble();
};

Regards,
Ben
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top