0

Can someone tell me if this is correct. I'm trying to overload my << operator for an array in my dynamic array class below.

Specefically,

Can I put std:ostream in the class itself? This does not seem corrrect. Compiler error is telling me it should only take one argument.

void print_array(std::ostream &os = cout) 
  { 
  for (int i = 0; i < size; i++) os << array[i] << endl; 
  } 
    std::ostream& operator<<(std::ostream& stream, dynamic_array const& data) 
  { 
  data.print_array(stream);
  return stream; 
  }

Dynamic Array Class

/*
Needs a reszie function added
Merge sort is better for sequential, stable(equal elements not re-arranged, or
*/
#include "c_arclib.cpp"

template <class T> class dynamic_array
  {
  private:
    T* array;
    T* scratch;
    void merge_recurse(int left, int right)
      {
      if(right == left + 1)
        {
        return;
        }
      else
        {
        int i = 0;
        int length = right - left;
        int midpoint_distance = length/2;
        int l = left, r = left + midpoint_distance;
        merge_recurse(left, left + midpoint_distance);
        merge_recurse(left + midpoint_distance, right);
        for(i = 0; i < length; i++)
          {
          if((l < (left + midpoint_distance)) && (r == right || array[l] > array[r]))
            {
            scratch[i] = array[l];
            l++;
            }
          else
            {
            scratch[i] = array[r];
            r++;
            }
          }
        for(i = left; i < right; i++)
          {
          array[i] = scratch[i - left];
          }
        }
      }
    void quick_recurse(int left, int right) 
      {  
      int l = left, r = right, tmp;
      int pivot = array[(left + right) / 2];
      while (l <= r)
        {
        while (array[l] < pivot)l++;
        while (array[r] > pivot)r--;
        if (l <= r) 
          {
          tmp = array[l];
          array[l] = array[r];
          array[r] = tmp;
          l++;
          r--;
          }
        }
      if (left < r)quick_recurse(left, r);
      if (l < right)quick_recurse(l, right);
      }  
  public:
    int size;
    dynamic_array(int sizein)
      {
      size=sizein;
      array = new T[size]();
      }
    void print_array(std::ostream &os = cout) 
      { 
      for (int i = 0; i < size; i++) os << array[i] << endl; 
      } 
    std::ostream& operator<<(std::ostream& stream, dynamic_array const& data) 
      { 
      data.print_array(stream);
      return stream; 
      }
    void print_array()
      {
      for (int i = 0; i < size; i++) cout << array[i] << endl;
      }
    int merge_sort()
      {
      scratch = new T[size]();
      if(scratch != NULL)
        {
        merge_recurse(0, size);
        return 1;
        }
      else
        {
        return 0;
        }
      }
    void quick_sort()
      {
      quick_recurse(0,size);
      }
    void rand_to_array()
      {
      srand(time(NULL));
      int* k;
      for (k = array; k != array + size; ++k)                                             
        { 
        *k=rand();                                      
        } 
      }
    void order_to_array()
      {
      int* k;
      int i = 0;
      for (k = array; k != array + size; ++k)                                             
        { 
        *k=i;
        ++i;        
        } 
      }
    void rorder_to_array()
      {
      int* k;
      int i = size;
      for (k = array; k != array + size; ++k)                                             
        { 
        *k=i;
        --i;        
        } 
      }
  };
int main()
  {
  dynamic_array<int> d1(1000000);
  d1.order_to_array();
  clock_t time_start=clock();
  d1.merge_sort(); 
  clock_t time_end=clock();
  double result = (double)(time_end - time_start) / CLOCKS_PER_SEC; 
  cout << result;
  }
1

2 Answers 2

1

Put the operator outside of your class:

template <class T> class dynamic_array
{
    ...
    // if you need to use protected/private members:
    friend std::ostream& operator<<(std::ostream& stream,
                                    dynamic_array<T> const& data);
}
template <class T>
std::ostream& operator<<(std::ostream& stream, dynamic_array<T> const& data) 
{ 
    data.print_array(stream);
    return stream; 
}
Sign up to request clarification or add additional context in comments.

9 Comments

compiler error is telling me dynamic_array is not a type...but it is clealy defined as you show above???
@ChrisAaker: forgot you need to repeat the template
it works not...I don't know why I wrote this monstrosity...except someone in code review told me it is a good idea...is it...the syntax makes me suicidal...I'm not so sure
@ChrisAaker: templates are scary at first, but they are beautiful if you learn to use them correctly.
will it works as a friend...other SO is telling me it should b global
|
1

Since the left operand of the operator<< will be the ostream, not the dynamic array object, you need to implement operator<< as a global function, not a member function (a member function overload is always invoked as object.operator<<(argument), so the object of which it's a member must be the left operand.

If that needs access to the internals of the object, you can make it a friend. If (as in this case) it uses only the public interface of the object (print_array, in your case), then it can just be a normal global function.

template <class T>
class dynamic_array {
    // ...
};

template <class T>
std::ostream &operator<<(std::ostream &os, dynamic_array<T> const &a) { 
    a.print_array(os);
    return os;
}

Personally, however, I'd probably make print_array a private member, and make the global operator<< a friend. This reduces the public interface of the class a bit (i.e., only one way to print a dynamic_array instead of two) with no loss of functionality (since the do precisely the same thing).

2 Comments

compiler does not recognize dynamic_array..saying it is not a type?
@ChrisAaker: Sorry -- I was condensing things a bit and didn't include all the template pieces that are needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.