Here's a simple pair of iterators that go in row-major and column-major order.
class row_iterator
{
    int (&arr)[3][3];
    std::size_t pos;
public:
    row_iterator(int (&arr)[3][3], std::size_t pos) : arr(arr), pos(pos) {}
    row_iterator& operator++() { ++pos; return *this; }
    row_iterator operator++(int) { auto that = *this; ++pos; return that; }
    int & operator*() { return arr[pos / 3][pos % 3]; }
    int * operator->() { return &arr[pos / 3][pos % 3]; }
    friend bool operator==(row_iterator lhs, row_iterator rhs) { return (lhs.arr == rhs.arr) && (lhs.pos == rhs.pos); }
    friend bool operator!=(row_iterator lhs, row_iterator rhs) { return !lhs == rhs; }
};
row_iterator row_begin(int (&arr)[3][3]) { return row_iterator(arr, 0); }
row_iterator row_end(int (&arr)[3][3]) { return row_iterator(arr, 9); }
class col_iterator
{
    int (&arr)[3][3];
    std::size_t pos;
public:
    col_iterator(int (&arr)[3][3], std::size_t pos) : arr(arr), pos(pos) {}
    col_iterator& operator++() { ++pos; return *this; }
    col_iteratoroperator++(int) { auto that = *this; ++pos; return that; }
    int & operator*() { return arr[pos % 3][pos / 3]; }
    int * operator->() { return &arr[pos % 3][pos / 3]; }
    friend bool operator==(col_iterator lhs, col_iterator rhs) { return (lhs.arr == rhs.arr) && (lhs.pos == rhs.pos); }
    friend bool operator!=(col_iterator lhs, col_iterator rhs) { return !lhs == rhs; }
};
col_iterator col_begin(int (&arr)[3][3]) { return col_iterator(arr, 0); }
col_iterator col_end(int (&arr)[3][3]) { return col_iterator(arr, 9); }