0

I have been trying to figure out expression templates since the last couple of days but haven't been able to get past this. I am building a matrix starting with the add operator. I am building using c++14. My matrix.h looks like this:

template <typename T, std::size_t COL, std::size_t ROW>
class Matrix {
public:
    using value_type = T;

    Matrix() : values(COL * ROW) {}

    static size_t cols() { return COL; }
    static size_t rows() { return ROW; }

    const T& operator()(size_t x, size_t y) const { return values[y * COL + x]; }
    T& operator()(size_t x, size_t y) { return values[y * COL + x]; }

    template <typename E>
    Matrix<T, COL, ROW>& operator=(const E& expression) {
        for (std::size_t y = 0; y != rows(); ++y) {
            for (std::size_t x = 0; x != cols(); ++x) {
                values[y * COL + x] = expression(x, y);
            }
        }
        return *this;
    }

private:
    std::vector<T> values;
};
template <typename LHS, typename RHS>
class MatrixSum
{
public:
    using value_type = typename LHS::value_type;

    MatrixSum(const LHS& lhs, const RHS& rhs) : rhs(rhs), lhs(lhs) {}

    value_type operator() (int x, int y) const  {
        return lhs(x, y) + rhs(x, y);
    }
private:
    const LHS& lhs;
    const RHS& rhs;
};
template <typename LHS, typename RHS>
MatrixSum<LHS, RHS> operator+(const LHS& lhs, const LHS& rhs) {
    return MatrixSum<LHS, RHS>(lhs, rhs);
}

Cpp file main function looks contains this:

Matrix<int,5,5>mx,my;
mx+my;

This shows the following error:

invalid operands to binary expression ('Matrix<int, 5, 5>' and 'Matrix<int, 5, 5>')
        mx+my;

I have searched a lot online, but I clearly have missed something. The above code is taken from https://riptutorial.com/cplusplus/example/19992/a-basic-example-illustrating-expression-templates. I would appreciate if some resources to understand expression templates can be shared.

Sarthak Agarwal
  • 128
  • 1
  • 2
  • 16
  • 2
    Your `operator+` contains `LHS` twice, one should be `RHS`. – Angew is no longer proud of SO Mar 05 '19 at 12:16
  • 2
    It helps to read the full error message. E.g. [here](http://coliru.stacked-crooked.com/a/dfc0664b5a6f8ed8), it says "note: couldn't deduce template parameter 'RHS'" This could have tipped you off (as it did me). – Angew is no longer proud of SO Mar 05 '19 at 12:18
  • Thank you @Angew. I'll make sure I read the full error message from now – Sarthak Agarwal Mar 05 '19 at 12:23
  • I never liked abusing the function call parameter as index operator. A bit more work, but if you return an intermediate class just containing an iterator to `values`, this one could define its own `operator[]` adding the appropriate offset to this stored iterator - allowing for `Matrix m; m[x][y];` syntax (if you like it...). – Aconcagua Mar 05 '19 at 12:46
  • I plan to do this once I am completed with the functionality. Instead of a vector, I am thinking of making a vector >. I plan on returning the xth row vector with operator[](Matrix) and returning yth cell with operator[](vector). I am basically doing polymorphism on the operator. Is this a good approach? @Aconcagua – Sarthak Agarwal Mar 05 '19 at 13:30
  • 2
    @SarthakAgarwal `vector>` is a very poor way of storing a rectangular matrix, you will kill your memory locality and introduce overhead (and potential for inconsistency errors), for zero benefit. Stick to a 1D array as you have now. You can still define a trivial helper class to support `m[i][j]` syntax. – Angew is no longer proud of SO Mar 05 '19 at 13:48
  • Okay, I did not know this. Thanks for the input @Angew. Kindly suggest some further reading. – Sarthak Agarwal Mar 05 '19 at 14:00
  • 1
    As a side-note: do not forget to pay attention to memory allocation for std:vector. Alignment is key to speed here. If neglected, you are going to suffer heavily in performance. Here's how I did it on an implementation I wrote years ago for my PhD: https://github.com/kvahed/codeare/blob/master/src/matrix/Allocator.hpp – Kaveh Vahedipour Mar 05 '19 at 15:02

0 Answers0