Thread: Traits/Promotion : specialisation problem for operator

  1. #1
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248

    Traits/Promotion : specialisation problem for operator

    Hi everyone,

    My compiler MSVS 2005 give an error when I try to compile a Matrix class with traits and policies for zero initialisation and return types.
    Here is a snippet of my Traits.h :
    Code:
    namespace LinAlg
    {
        template<typename T1, typename T2>
    	struct ReturnType;
    
        // partial specialisation for Complex - I
        template<>
    	struct ReturnType<Complex, Complex>
    	{
    	    typedef Complex Return;
    	};
        // partial specialisation for Complex - II
        template<>
    	struct ReturnType<Real, Complex>
    	{
    	    typedef Complex Return;
    	};
        // partial specialisation for Complex - III
        template<>
    	struct ReturnType<Complex, Real>
    	{
    	    typedef Complex Return;
    	};
    
        // specialisation for Real: Real return type iff both arguments Real
        template<>
    	struct ReturnType<Real, Real>
    	{
    	    typedef Real Return;
    	}; 
    }; // end namespace
    and this is my (free) operator+ template:
    Code:
        // addition
        template<typename T1, typename T2> Matrix<typename ReturnType<T1, T2> :: ResultT>
            operator+( Matrix<T1> const& A1, Matrix<T2> const& A2)
            {
                Matrix<typename ReturnType<T1, T2> :: ResultT> result( A1);
                return ( result += A2);
            }
    The error message is
    with most important line:
    [cc] testMatrix.cpp
    [cc] D:\V5.1.0\visual.static.frame.HEAD\must\com.airbus .must.static.data.service\src\pluginlib\cxx\test\t estMatrix.cpp(55) : error C2893: Failed to specialize function template 'LinAlg :: Matrix<
    ReturnType<T1,T2>::ResultT> LinAlg :: operator +(const LinAlg :: Matrix<T> &,const LinAlg :: Matrix<T2> &)'
    [cc] With the following template arguments:
    [cc] 'Real'
    [cc] 'Complex'
    Thanks a huge lot for your help!!!
    Last edited by MarkZWEERS; 11-04-2008 at 04:29 AM.

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    ReturnType defines a type called Return, whereas later you use ReturnType<T1, T2>::ResultT?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  3. #3
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    Yes, you're right! Frustrating how I sometimes can just not see these small errors, probably I've been looking too long to the same lines.

    However, this error revealed an old fundamental question for me, which is the reason that I did not use this class template for the time being.
    In my operator+ , I use the copy-constructor
    Code:
    Matrix(Matrix<T> const&);
    Now my policy is that
    Complex + Real = Complex
    Complex + Complex = Complex
    Real + Complex = Complex
    Real + Real = Real

    But: at the usage of the copy-constructor, I do not know a priori which of the two arguments is of the "broader" type Complex. I will thus need cast-constructors, which change the 'typename T = Real' to 'typename T = Complex' of the argument.

    edit:

    here's an example which fails:
    Code:
      CMatrix Z(20);
      RMatrix A(20);
      A + Z;                 // fails
    here's an example which works:
    Code:
      CMatrix Z(20);
      RMatrix A(20);
      Z + A;                 // works


    How can I do this?

    Thanks a lot for your help!!!
    Last edited by MarkZWEERS; 11-04-2008 at 06:20 AM.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Write the cast constructors.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    yes, yes... but that's exactly what I just don't know.

    here is a snippet of the constructors:
    Code:
        template<typename T>
    	class Matrix
    	{
    	public:
    	Matrix();
    	explicit Matrix(size_t const&);
    	Matrix(size_t const&, size_t const&);
    	Matrix(Matrix<T> const&);
    Should I do something like
    Code:
        template<> Matrix<Complex>(Matrix<Real>&);
    and than do something with the 'T' of "this" ?

    I really don't know how to change the specialisation of a class in its cast constructor.

    Thanks!

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, what does the copy constructor look like? Probably something like:
    Code:
    template <typename T>
    Matrix<T>::Matrix(const Matrix<T> &o)
     m_data(o.m_data)
    {
    };
    under the assumption that m_data is a std::vector<T> or something like that.
    Then a converting constructor looks like this:
    Code:
    // prototype:
      template <typename U>
      Matrix(Matrix<U> const&);
    
    // Impl:
    template <typename T>
    template <typename U>
    Matrix<T>::Matrix(Matrix<U> const&o)
      : m_data(o.m_data.begin(), o.m_data.end())
    {
    }
    Pretty trivial there. You might want to make this constructor explicit - depends on whether you want implicit conversion between the matrix types.

    Anyway, this constructor will fail to instantiate if U is not assignable to T. That's fine.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    No, I guess I have not well explained my problem.

    My class has got an element-vector " std::vector<T> _elms"

    Let's say I have
    Code:
    Matrix<Real> A;
    this will instantiate the element-vector with T = Real.

    Now I understand that the cast constructor is just a templatised version of the copy constructor here, but:

    How will I change the specialisation of this element-vector ?
    Last edited by MarkZWEERS; 11-04-2008 at 08:01 AM.

  8. #8
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You don't change anything. When you create a Matrix<Complex>, it contains a vector<Complex>. When you want to initialize that vector with the vector<Real> from a Matrix<Real>, you just copy the elements, using the range constructor, as I've shown. This assumes that Complex has a constructor that takes a Real, but that would be trivial to implement.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  9. #9
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    :-) I thought that it was actually created as soon as the constructor was called. Thank you!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM