Yes Imhere
Yes Imhere

Reputation: 37

Return ith row of 2d array as a vector

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];
        }
    }
}

Upvotes: 2

Views: 318

Answers (1)

Barry
Barry

Reputation: 302767

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]);

Upvotes: 2

Related Questions