Specialization errors

Discussion in 'C++' started by pmatos, Sep 9, 2005.

  1. pmatos

    pmatos Guest

    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
     
    pmatos, Sep 9, 2005
    #1
    1. Advertising

  2. pmatos

    benben Guest

    "pmatos" <-id.pt> wrote in message
    news:...
    > 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
    >
     
    benben, Sep 9, 2005
    #2
    1. Advertising

  3. pmatos

    pmatos Guest

    benben wrote:
    > "pmatos" <-id.pt> wrote in message
    > news:...
    > > 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)
    > {
    > // ...
    > }
    >
    >


    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)
    > {
    > // ...
    > }
    >


    Probably this is the solution but won't this conflict with Matrix<T>
    methods?

    >
    >
    > >
    > > ...
    > >
    > > }
    > >
    > > 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
    > >
     
    pmatos, Sep 9, 2005
    #3
  4. pmatos

    pmatos Guest

    benben wrote:
    >
    > 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!
     
    pmatos, Sep 9, 2005
    #4
  5. pmatos

    Greg Guest

    pmatos wrote:
    > benben wrote:
    > >
    > > 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!


    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
     
    Greg, Sep 10, 2005
    #5
  6. pmatos

    benben Guest

    "pmatos" <-id.pt> wrote in message
    news:...
    >
    > benben wrote:
    >>
    >> 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!
    >


    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
     
    benben, Sep 10, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mark Goldin

    Errors, errors, errors

    Mark Goldin, Jan 17, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    985
    Mark Goldin
    Jan 17, 2004
  2. SenthilVel
    Replies:
    0
    Views:
    961
    SenthilVel
    Jun 7, 2006
  3. George1776

    Out-of-memory errors and caching errors.

    George1776, Aug 28, 2006, in forum: ASP .Net
    Replies:
    2
    Views:
    1,316
    George1776
    Sep 14, 2006
  4. Joseph Turian
    Replies:
    2
    Views:
    480
  5. Lance Wynn
    Replies:
    1
    Views:
    1,876
    Lance Wynn
    Feb 3, 2008
Loading...

Share This Page