2

Hi I'm currently trying to implement a templated library for matrices, so I'm implementing some operations like the transpose() operations.

I'd also like that the matrices returned by the operators, like transpose, to share the data with the original matrix.

Example:

matrix <int> x(3,3);
x.transpose() [2][1] = 42;

then if i read x[1][2] must be 42.

Any ideas from where could I start?.

Thanks in advance

DevSolar
  • 67,862
  • 21
  • 134
  • 209
liquidmind
  • 21
  • 1
  • Write a [proxy type](https://en.cppreference.com/w/cpp/utility/bitset/reference). – Passer By Nov 13 '18 at 16:17
  • 1
    @PasserBy: What's with the reference to `std::bitset`? I don't see the relevance, really. – DevSolar Nov 13 '18 at 16:20
  • 1
    You could have the return type of `transpose()` be `matrix&` and return `*this`. – Pixelchemist Nov 13 '18 at 16:21
  • @DevSolar Just the first proxy in the standard library I thought of that isn't from `std::vector`, as an example. – Passer By Nov 13 '18 at 16:21
  • Generally speaking, unclear. Is `matrix::transpose` intended to *modify* the original `matrix`, or returning a *new*, transposed matrix (as your code sample seems to indicate)? Or could `matrix::transpose` return a new matrix that *references* the original matrix data instead of holding its own copy of it? That significantly impacts where you *could* start... – DevSolar Nov 13 '18 at 16:25
  • @PasserBy: A proxy class is *one possible* way to solve the issue, not *the only* way. Hence, not a duplicate, and IMHO bad style to vote-to-close as such. – DevSolar Nov 13 '18 at 16:27
  • @DevSolar, from the question it is clear that it should hold a reference: *then if i read x[1][2] must be 42*. – Evg Nov 13 '18 at 16:30
  • @DevSolar A fair argument. But in this case there is no other way the syntax is going to work. Then there are the two answers that failed without proxies and one that is exactly a proxy. – Passer By Nov 13 '18 at 16:31
  • @liquidmind: All other considerations aside, be aware of [OpenCV](https://opencv.org/), [Boost.uBLAS](https://www.boost.org/doc/libs/1_68_0/libs/numeric/ublas/doc/index.html) and other libraries that come with readily usable matrix datatypes and operations. – DevSolar Nov 13 '18 at 17:04
  • ok!. Thanks to everyone for the replying. I'd like to do it from scratch just because I think it may be a good way to exercise. But, I'll consider those libraries if I need them. Many thanks!. – liquidmind Nov 13 '18 at 17:11

2 Answers2

1

Something along the following lines:

template<class Matrix>
struct Transposed
{
    Transposed(Matrix& matrix) : matrix_(matrix)
    { }

    decltype(auto) operator()(int row, int col)
    {
        return matrix_(col, row);
    }

    Matrix& matrix_;
};

template<typename T>
struct Matrix
{
    auto transposed()
    {
        return Transposed<Matrix>{*this};
    }

    ...
};

If you implement a matrix from scratch, I don't see why [i][j] syntax should be preferred to (i, j) which is easier to implement.

Evg
  • 25,259
  • 5
  • 41
  • 83
  • Oh I see. Yes, I'm indeed implementing it like (i,j). Btw this hint could actually work. I'll try it now on paper .. many thanks! – liquidmind Nov 13 '18 at 16:31
-1

I think you can use casting operators. A simple sample may be:

class x {
public:
    operator matrix&() { return transpose(); }
protected:
    auto transpose() -> matrix & { 
        /* returning the matrix  */
    }
};
mamooot
  • 7
  • 2