2

I'm trying to overload [ ] for 2d arrays so that, for example, a[1] converts the first row of the 2d array into a vector and returns it. Then a seperate function that takes it and prints out the entire vector.

matrix<int> a;    //pointer ** points to array of pointers which point to their respective array
...
PrintVec(a[0])    //print first array as a vector

Here's what I have so far, I'm not sure how to really approach this. But this is the general idea

//overload [] to create vector from single array from 2d array
matrix<T> operator[] (int i){
    vector<T> temp(array_[i][], num_cols_);   //create vector of size column then
                                              //copy ith array (pointer pointing to ith row) from 2d array into vector
    return temp;
}

template <typename T>         //I'm sure this is wrong
void PrintVec(vector<T> & v){
    for (auto i = v.begin(); i != v.end(); i++){
        cout << v[i] << " " << endl;
    }
}

Edit: Here's the implementation of matrix

private:
        size_t num_cols_;
        size_t num_rows_;
        Comparable **array_;
public:
        void ReadMatrix();

template <typename T>
void matrix <T>::ReadMatrix(){
    cout << "Enter rows:" << endl;
    cin >> num_rows_;
    cout << "Enter columns:" << endl;
    cin >> num_cols_;

    array_ = new T*[num_rows_];
    for (int i = 0; i < num_rows_; i++){
        array_[i] = new T[num_cols_];
    }

    cout << "Enter values for matrix:" << endl;
    for (int j = 0; j < num_rows_; j++){
        for (int k = 0; k < num_cols_; k++){
            cin >> array_[j][k];
        }
    }
}
Yes Imhere
  • 37
  • 4
  • Shouldn't a[1] return the 2nd row of the 2D array? Array numbers conventionally start from 0. – Rahul Kadukar Sep 10 '15 at 18:30
  • Yes sorry, I'll edit it out since it's irrelevant. But I do need a[1] to print first row when I'm finished with my program – Yes Imhere Sep 10 '15 at 18:32
  • `matrix operator[] (int i)` returns a `matrix`, not a `vector`. – Jonathan Potter Sep 10 '15 at 18:33
  • I thought that was wrong. But I don't know how else to overload [ ] for the matrix in order to return a vector – Yes Imhere Sep 10 '15 at 18:36
  • Why not store the data in a vector of vectors in the first place? If `array_` is `vector` then returning a row vector comes free. It's just `return array_[row];` – user4581301 Sep 10 '15 at 19:01
  • And a convenience thing: Since your Matrix is a template, don't bother splitting it up. Implement the methods inside the class definition. [You can't hide the implementation details of a template](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file), so separating the definition and the implementation definition gets you nothing. – user4581301 Sep 10 '15 at 19:16

1 Answers1

2

Two things. First, that's the wrong constructor. It probably won't compile for most types, but for integral Ts you're ending up with:

 vector( size_type count, 
         const T& value,
         const Allocator& alloc = Allocator());

What you want to do is copy the elements - not get the same element num_cols_ times (which is what you would get if you flipped the ordering of arguments, right now you're actually getting the value num_cols_ repeated array_[i][0] times).

The correct constructor is:

template< class InputIt >
vector( InputIt first, InputIt last, 
        const Allocator& alloc = Allocator() );

Which is to say:

vector<T> operator[] (int i){
    return vector<T>{&array_[i][0], &array_[i][num_cols_]};
}

And then with PrintVec, you're taking the argument by reference to non-const. But this won't let you pass a temporary. You should instead take your argument as reference to const:

template <typename T>
void PrintVec(vector<T> const& v) { ... }

That would let you do:

PrintVec(a[0]);
Barry
  • 286,269
  • 29
  • 621
  • 977
  • The general idea is correct, but it's hard to say whether the actual implementation is correct or not without seeing the implementation of his matrix class. In particular, watch out for an access one past the end in your second argument to the constructor. If the vector has debugging active, this may crash. A better solution would be to obtain iterators from the underlying representation, and use them; how to do this depends on the underlying representation, however. – James Kanze Sep 10 '15 at 18:40
  • I posted the implementation, I'm not sure if this changes anything. Either way thanks for the answer. Edit nevermind, your solution works great. Thanks so much – Yes Imhere Sep 10 '15 at 18:45