Solved

Template array class stuff

Posted on 1998-06-04
8
207 Views
Last Modified: 2010-04-01
I have this template array class decl:

// Base template 1D      
template <class Type, int low, int high,int D> class A1D
{
  public:
       
   A1D(void): element(new Type[high-low+1]) { }
   ~A1D() { delete [] element; }

   Type& operator[](const int i) {
          if(i<low || i>high) {
            //throw(RangeException(D,low,high,i));
              cout << "Array out of range error !!" << endl;
              //return((Type&)0);
          }
        return element[i-low];
   }

   operator Type*() {
          return(element);
   }
           
   inline int begin() const {return low;}
   inline int end()   const {return high;}
   inline int dim()   const {return D;}
       
  private:
   //Type *element[high-low+1];
   Type *element;
};

// 2D      
template <class Type, int L1, int H1, int L2, int H2,int D>
class A2D : public A1D<A1D<Type,L2,H2,1>,L1,H1,D>
{
       
};

// 3D      
template <class Type, int L1, int H1, int L2, int H2, int L3, int H3, int D>
class A3D : public A1D<A2D<Type,L2,H2,L3,H3,2>,L1,H1,D>
{
     
};

In a program I declare the following:

A3D<int,0,5,0,5,0,5,3> arr;    // NOTE:  ( I know what you are thinking, but my compiler cannot handle default                                                   //                 template args..)


i also a have:

void foo(int a[][5][5])

I want to pass arr to foo, but the compiler complains of a type mismatch.


0
Comment
Question by:migue
  • 4
  • 3
8 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 1165230
That's not suprising.

arr is a class.  It is a class that acts like an array, but it is a class.
foo takes an array.  

The two are not the same.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1165231
You could declare foo to take a A3D<int,0,5,0,5,0,5,3>  like

void foo(A3D<int,0,5,0,5,0,5,3> a)
0
 

Author Comment

by:migue
ID: 1165232
nietod: I know the two are not the same. But can i code an operator for the class to take care of this problem ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 1165233
an operator to do what?  A conversion operator?  You can't realistically make a conversion operator because your class stores the data in the wrong format.  You could dynamically allocate memory of the right format and fill it it, but then you would have a memory leak.  You could use a proxy class to take care of the memory deletion, but then your conversion wouldn't work automatically.  So you would be forced to use an ugly syntax and it would be very innefficient.

I wouldn't recommend it.  I suggest you look into alternatives.  What is it that you are hoping to accomplish?

Or am I missunderstanding what you meant about an opperator?
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:migue
ID: 1165234
What I am trying to accomplish is that I want the template array class to behave as much as possible to regular 'C' arrays. If I cannot pass it to a function expecting a n-dimensional array of the same type(int,char,double...) then I am out of luck.

I have tested this class...it has no memory leaks that I know.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1165235
It has no memory leaks at the moment.  But you would have a hard time writing a conversion operator that didn't have a memory leak.

I think you are out of luck.

Your options are...

1.  write fuctions that take  the class instead of the c array.
2.  write a fucntion to create a c-array from the class.  But you will have cleanup issues.
3.  redesign your class to be memory compatible with c arrays--this is a big change with some serious dissadvantages, but also some major advantages.  You will get great flexibilty at the price of many compile time error checks.  

Opption 1 is probably the best.
0
 
LVL 2

Accepted Solution

by:
abesoft earned 80 total points
ID: 1165236
First, you will have trouble because one array is [][5][5] and the other is [][6][6].  However, if you change the requirement so that you want ot pass to a [][6][6] then here is one solution.

(This uses a class that uses c-compatable arrays as the underlying storage.  I agree with nietod that this is the only reasonable approach....)

#include <iostream.h>

// Base template 1D        
template <class Type, int l1, int h1, int l2, int h2, int l3, int h3, int D> class A3D
{
  public:
     
      typedef Type t_array [h1-l1+1][h2-l2+1][h3-l3+1];

   A3D(void) { }
   ~A3D() { }

   struct A1D {
       A3D<Type,l1,h1,l2,h2,l3,h3,D> &owner;
       int index, subIndex;
       A1D( A3D<Type,l1,h1,l2,h2,l3,h3,D> &o, int i, int s):
               owner( o), index(i), subIndex( s)
       {}
       Type &operator[]( int subSubIndex)
       {   return owner.get( index, subIndex, subSubIndex);}
   };

   struct A2D {
       A3D<Type,l1,h1,l2,h2,l3,h3,D> &owner;
       int index;
       A2D( A3D<Type,l1,h1,l2,h2,l3,h3,D> &o, int i): owner( o), index(i)
       {}
       A1D operator[]( int subIndex)
       {   return A1D( owner, index, subIndex);}
   };

   A2D operator[](const int i) {
        return A2D( *this, i);
   }
   
   int &get( int i1, int i2, int i3)
   {
       if ((i1 < l1) || (i1 > h1) || (i2 < l2) || (i2 > h2) || (i3 < l3) || (i3 > h3))
           cerr << "Ack!" << endl;
       return element[i1-l1][i2-l2][i3-l3];
   }


   operator t_array&() {return element;}
           
   inline int begin() const {return low;}
   inline int end()   const {return high;}
   inline int dim()   const {return D;}
       
  private:
   t_array element;
};

void foo(int a[][6][6])
{
}


void main()
{
  A3D<int,0,5,0,5,0,5,3> arr;

  arr[1][1][1] = 5;
 
  foo(arr);
}
Note that the class should also be extended to be const-correct, and probably exceptions should be used to handle the error (which this code will actually flame on...) I guess these are excercises for the reader ;)

Hope this helps!
0
 

Author Comment

by:migue
ID: 1165237
thanks guys..I guess I took the wrong design approach.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now