Is it possible to get an entire column of a 2D matrix which is implemented as std::vector<std::vector<int32_t>>
. We all know we can access an entire row using range for loop like for(const auto& row : matrix)
. Is there a similar way to access an entire column using range for loop like for(const auto& col : matrix)

- 2,177
- 1
- 19
- 33
-
no you cannot..as it is a vector of vectors and each vector is represented as a row. – vinod Sep 13 '20 at 06:45
-
@vinod can you suggest any other STL container that has this kind of feature. I should be able to access an entire row or an entire column – Harry Sep 13 '20 at 06:49
-
There is no STL container available but you can do it by running a for loop to get all the elements in the front of each vector and put these elements in a new vector. – vinod Sep 13 '20 at 06:51
-
@vinod _"and each vector is represented as a row"_ Where did you get that from? – πάντα ῥεῖ Sep 13 '20 at 06:55
-
@πάνταῥεῖ memory traditionally considered sequenced as a row. So matrix expected be stored by rows. Exceptions exist, like OpenGL which stores matrices as columns and uses right-handed coordinate system to match, for optimization purposes – Swift - Friday Pie Sep 13 '20 at 08:10
-
Better not to use vector of vectors as a matrix, unless you need an array with ragged edge. Performance is awful, the storage they use is not monotonous, and use of your own allocator to negate it is problematic. Use class that encapsulates single-dimensional container (vector) and `operator()`, (or `[]` but that be untrivial task) which would allow you to index matrix. – Swift - Friday Pie Sep 13 '20 at 08:17
-
For iterating through columns, create an adapter class – Swift - Friday Pie Sep 13 '20 at 08:21
-
@Swift Well, the question was if it is possible, and it is more or less. I never had doubts that this is a suboptimal solution. I know, that storing all the matrix elements using a contiguous array, would be the better solution, and that needs to be wrapped at the surface to allow efficient and convenient access of course. – πάντα ῥεῖ Sep 13 '20 at 08:31
3 Answers
It is possible using range based for loops, to access the column values, you just have a fixed index:
for(const auto& row : matrix) {
cout << row[5] << endl; // 5 is the fixed column index
}
From knowing that it's possible to write a little helper function which extracts a complete column into another std::vector<>
:
std::vector<int> extract_column(const std::vector<std::vector<int>>& matrix, int col_idx) {
std::vector<int> result;
for(const auto& row : matrix) {
result.push_back(row[col_idx]);
}
Here's a complete example:
#include <iostream>
#include <vector>
std::vector<int> extract_column(const std::vector<std::vector<int>>& matrix, int col_idx) {
std::vector<int> result;
for(const auto& row : matrix) {
result.push_back(row[col_idx]);
}
return result;
}
int main() {
std::vector<std::vector<int>> matrix =
{ { 1, 2, 3 } ,
{ 4, 5, 6 } ,
{ 7, 8, 9 }
};
// print the middle row
for(auto elem : extract_column(matrix,1)) {
std::cout << elem << std::endl;
}
}
Output
2
5
8
See the online demo
That said, it should be noted that a std::vector<std::vector<T>>
as solution for a matrix representation is suboptimal.
The better fit would be to represent all the matrix elements (for arbitrary dimensions) as a contiguous array, and apply some basic math, to access certain (groups) of matrix elements. The std::vector<std::vector<T>>
uses separate allocations for the row elements
To illustrate:
+-+-+-+
row 1 |1|2|3|
+-+-+-+
+-+-+-+ +-+-+-++-+-+-++-+-+-+
row 2 |4|5|6| => |1|2|3||4|5|6||7|8|9|
+-+-+-+ +-+-+-++-+-+-++-+-+-+
+-+-+-+
row 3 |7|8|9| row 1 row 2 row 3
+-+-+-+
But how to this exactly would lead too far here, and was already answered in other questions at SO, and realized by a number of math frameworks.

- 1
- 13
- 116
- 190
-
@vinod `row` is already a single dimension vector in the range for loop. You cannot use row[5][0]. – Harry Sep 13 '20 at 07:01
-
-
1@vinod Not really, because you're saying _it's not possible_, while it's provenly possible. Your comment have not much relevance anyways. – πάντα ῥεῖ Sep 13 '20 at 07:10
-
so can u access the complete column like he got the row in the question? answer is NO what i commented in question. You did it using for loop which i also mentioned on the comment. And don't be toxic – vinod Sep 13 '20 at 07:14
-
@vinod Sorry, seems we completelya misunderstood each other. I changed my answer now according to what was in question. – πάντα ῥεῖ Sep 13 '20 at 07:29
While I see no way to do this with the actual std::vector
, what you could do would be to implement your own class Matrix
which stores a 2D vector (or which even inherits from one, which I don't recommend though - especially I'd make sure that my matrix class never contains a jagged array).
If you have done that, you could then create another class Column
, which looks somewhat like this:
class Column
{
private:
Matrix* target; // << consider rather using smart pointers here
size_t column_index;
public:
int32_t& operator[](size_t index) { return (*target)[column_index][index]; }
const int32_t& operator[](size_t index) const { return (*target)[column_index][index]; }
};
So far so good, you now have a column class that accesses some matrix. Simplest approach would now be to also have some method for the size (that again accesses the matrix class) and then do a old fashioned for loop, for(size_t i=0; i<size; i++)
...
If you now want a range based loop instead, what you'd have to do is to give Column
an inner class Iterator
that behaves as iterator and give Column
two methods begin()
and end()
which each return a fitting Iterator
.
class Column
{
...
public:
...
size_t size(); // I omit the details here
class Iterator
{
...
};
Iterator begin() { return Iterator(this, 0); }
Iterator end() { return Iterator(this, size()); }
};
This would be the base structure of such an iterator being used. Note that you'd had to actually write two such classes, one being constant.
Inside the iterator would look somewhat like this:
class Column::Iterator
{
private:
Column* father;
size_t index;
public:
Iterator(Column* father, size_t index) : father(father), index(index { }
Iterator operator++() { Iterator i = *this; i.index++; return i; }
Iterator operator++(int) { index++; return *this; }
int32_t& operator*() { return (*father)[index]; }
int32_t* operator->() { return &((*father)[index]); }
bool operator==(const Iterator& other) { return father == other.father and index == other.index; }
bool operator!=(const Iterator& other) { return not operator==(other); }
};
Note that I haven't tested the code.
How to make the for each loop function in C++ work with a custom class https://codereview.stackexchange.com/questions/74609/custom-iterator-for-a-linked-list-class https://gist.github.com/jeetsukumaran/307264

- 3,652
- 3
- 18
- 36
You need a column access facet. Your facet will have:
- a reference to the matrix, e.g.
m_matrix
- the column number, e.g.
m_column
You specify the matrix and the column number to construct the facet. Then you need to define operator[] (row) { return this ->m_vector [row] [this ->m_column]; }
. HTH.

- 454
- 2
- 6