Reputation: 13257
I have defined two dimensional array using following definition
typedef std::vector<std::vector<short> > table_t;
Can I use std::for_each
for this array, I want to pass row
and col
as a parameter to the function
Or is there a way to identify row
and col
in the function
following is the code to get more idea.
#include <vector>
#include <iostream>
#include <algorithm>
typedef std::vector<std::vector<short> > table_t;
void myfunction (int i) {
std::cout << " " << i;
}
int main ( int argc , char **argv) {
table_t t = table_t(5, std::vector<short>(5));
int counter = 0;
for (size_t row = 0; row < 5; ++row)
for (size_t col = 0; col < 5; ++col)
t[row][col] = counter++;
std::for_each( t.begin(), t.end(), myfunction);
return 0;
}
Upvotes: 3
Views: 2853
Reputation: 392911
Strictly speaking, I think you'd want std::array<std::array<short, 5> ,5>
intead of the vector-of-vector (making sure all rows are of equal length and optimizing storage).
If your compiler already supports template aliases you can use one to get 'pretty' declaration:
template <class T, size_t R, size_t C>
using matrix = std::array<std::array<T, C>, R>;
// use it simply like:
matrix<short, 5, 5> t;
Here is a rough draft that can do both, based on C++11
#include <array>
#include <vector>
#include <iostream>
template <typename M, typename F>
void for_matrix(M& matrix, F f)
{
size_t r = 0;
for (auto& row : matrix)
{
size_t c = 0;
for (auto& cell : row)
f(cell, r, c++);
r++;
}
}
void sample_function(short& data, size_t row, size_t col)
{
std::cout << "(" << row << ", " << col << "): " << data << std::endl;
}
int main()
{
// based on vector:
typedef std::vector<std::vector<short> > table_t;
table_t t = table_t(5, std::vector<short>(5));
for_matrix(t, sample_function);
for_matrix(t, [] (short&i,size_t,size_t) { std::cout << "lambda: " << i << std::endl; });
// based on std::array:
std::array<std::array<short, 3>, 4> a;
for_matrix(a, [] (short&i,size_t,size_t) { i = 0; });
for_matrix(a, sample_function);
}
Upvotes: 1
Reputation: 4025
c++98
void SomeThingElse(int row, int col)
{
// Impl.
}
struct Fun
{
private:
int col_m;
int row_m;
public:
Fun(int row) : row_m(row) { }
void operator()(int x) const
{
SomeThingElse(row_m, x);
}
};
void SomeFun(const std::vector<short>& cols)
{
static int row = 0;
++row;
std::for_each( cols.begin(), cols.end(), Fun(row));
}
std::for_each(table_t.begin(), table_t.end(), SomeFun);
c++11. ( Just to show how easy it would be ). ( EDIT )
int row = 0;
std::for_each( begin(table_t), end(table_t), [&]( const std::vector<short>& col)
{
row++;
int temp = row;
std::for_each( begin(col), end(col), [=](int x )
{
fn(temp, x);
});
});
Upvotes: 2
Reputation: 361352
I think the solution is custom function object. Try something like this:
struct process_col
{
int row_index;
int col_index;
process_col(int r) : row_index(r), col_index(0){}
void operator()(short & data)
{
//use row_index, col_index, and data at this indices
std::cout << "Value at (" <<row_index <<"," << col_index << ") is " << data << std::endl;
col_index++; //at the bottom
}
};
struct process_row
{
int row_index;
process_row() : row_index(0){}
void operator()(std::vector<short> & row)
{
std::for_each(row.begin(), row.end(), process_col(row_index));
row_index++;
}
};
And then use it as:
std::for_each( t.begin(), t.end(), process_row());
Online Demo : http://ideone.com/Dft8X
Output:
Value at (0,0) is 0
Value at (0,1) is 1
Value at (0,2) is 2
Value at (0,3) is 3
Value at (0,4) is 4
Value at (1,0) is 5
Value at (1,1) is 6
Value at (1,2) is 7
Value at (1,3) is 8
Value at (1,4) is 9
Value at (2,0) is 10
Value at (2,1) is 11
Value at (2,2) is 12
Value at (2,3) is 13
Value at (2,4) is 14
Value at (3,0) is 15
Value at (3,1) is 16
Value at (3,2) is 17
Value at (3,3) is 18
Value at (3,4) is 19
Value at (4,0) is 20
Value at (4,1) is 21
Value at (4,2) is 22
Value at (4,3) is 23
Value at (4,4) is 24
Upvotes: 3