Question

I have been struggling to figure out how to implement the following classes. Essentially what I am trying to achieve is the following: - The main class is for a Matrix - The data should be stored external to the Matrix object - The Matrix_Data should be able to support both float and double types

I've been trying to work on figuring out how to implement with templates, but I cannot seem to figure it out. This gives a general idea of my intent:

template <typename T>
class Matrix {
private:
   IMatrix_Data* m_data;
...
}

class IMatrix_Data { 
XXX Get_Data();  // <== The return type should be float or double, as appropriate
...
}

Can someone please give me some suggestions and some guidance?

UPDATE:

I have updated the class following @ruslo's suggestion. The problem that I'm now facing is that changing the Matrix and Matrix_Data into template classes causes a chain effect to a large number of classes. I admit that my experience with templates is very limited --- perhaps I'm going about this the wrong way, or perhaps this is the right way but it just looks wrong to me.

Basically, it would seem that any class which then uses a Matrix, or the data stored in a matrix needs to be a template class. I know that I can clean up the appearance of the code with typedef (or using statements), but I don't think that will change anything in terms of the hierarchy of classes, will it?

As an example of some classes which I have that use Matrix:

template <typename T>
class Vector : Matrix<T>

template <typename T>
class Input {  // <- this class is intended to be used as a base class for runtime polymorphism
    Vector<T>::DataType Get_Data();
    /* Rest of class */
};

class Parameterized_Input{ // <- this class is intended to be used as a base class for runtime polymorphism
};

template <typename T>    
class Input_Iterator {
    /* ...
           */
    std::stack<std::vector<Input<T>* >::iterator > parent_nodes; // Part of the iteration algo
}

I'm feeling rather confused here --- this is a little beyond anything I've done before and I'm hoping someone can help point me in the right direction here, both in terms of the implementation as well as any suggestions for improving the design.

For example, as I noted in the code above, the class Input is intended to be an abstract base class, to allow runtime polymorphism. Derived classes will implement this interface (and possibly Parameterized_Input) to create different types of Inputs. However, since the return type of the inputs is the same as that of the Matrix_Data -- i.e. unknown type T right now -- it seems that I will need to make every derived class into a template as well.

Unfortunately, at this time, I feel that I need the flexibility of using either a float for performance or double for precision, depending on the circumstances. If I could rule one of these out, then it would certainly simplify everything.

The alternative -- without templates, almost appears to be simpler in the big picture (based on my possible faulty understanding):

class Matrix{
    IMatrix_Data* m_data;
    /*  ...   */
}

class IMatrix_Data{
    /*  ...   */
    template <typename T>
    Get_Data(int _row,int _col) { return static_cast<T>( this->ncols * _col + _row ); }
}

namespace matrix_data {
    class MD_Double : public IMatrix_Data{
        /*  ...   */
    }

    class MD_Double : public IMatrix_Data{
        /*  ...   */
    }

I've tried to provide enough information above, but if there's anything missing, please let me know and I'll be happy to provide additional clarification and/or information.

Thanks and regards, Shmuel

Was it helpful?

Solution

Return value of GetData can be template parameter:

template <class T>
class MatrixImpl {
 public:
  typedef T DataType;
  DataType GetData();
};

template <class T>
class Matrix {
 public:
  typedef MatrixImpl<T> Impl;
  typedef typename Impl::DataType DataType;

  DataType GetData() {
    return data_->GetData();
  }

 private:
  Impl* data_;
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top