3
\$\begingroup\$

I have a class called IntMatrix which has 2 fields:

Dimensions dimensions;//To save height and width of my matrix
int *data;//For saving data

and I need to override the operators >,>=,<,<=,==,!= which take a scalar and compare each single value in my matrix with that scalar accordingly, and returns a new matrix with the same size that contains 1 if the comparison returned true and 0 else.

For example:

mat: {1,2,3;4,5,6}

mat_2 = mat > 3;//Should return {0,0,0;1,1,1}

So, you may notice that all my functions have the exact lines of code except whenever I wrote != it should be > or < or == or etc....

So, in order to remove duplication here's how I implemented them:

IntMatrix IntMatrix::operator<(int num) const {
    return filter(*this,Between(INT_MIN,num-1));
}

IntMatrix IntMatrix::operator>(int num) const {
    return filter(*this,Between(num+1,INT_MAX));
}

IntMatrix IntMatrix::operator!=(int num) const {
    return filter(*this,Between(num,num), true);
}

where Between is a functor (to replace a pointer to a function).

So, when I reviewed my code I strongly believe this is not the best solution to give to this kind of problem, since filter() won't be well understandable by other programmers.

From your experience is there anyway to improve this code?

(I know that macros would be perfect here but don't want to use them either since they are a bad practice)

Note: I am working with C++11 and want only to use standard libraries.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Generally we like to see the whole class, both the header file and the C++ source file for the full context. It is very hard to provide a good review with only pieces of the code presented. \$\endgroup\$
    – pacmaninbw
    Jun 8, 2020 at 22:22
  • \$\begingroup\$ Generally, you shouldn't make operators like < and == that return something else other than bool. It might cause issues on some level. In Matlab they have special bitwise operators but it will be hard to do in C++. Consider making functions instead of operators. \$\endgroup\$
    – ALX23z
    Jun 10, 2020 at 5:14

1 Answer 1

5
\$\begingroup\$

Make use of the standard library

This looks like a job for std::transform(), which in many other languages would be the equivalent of the map function. It works on iterators, so it would help if your class provides begin() and end() functions, or if internally you store values in a std::vector. However, the data pointer can be used as well.

Then, it's possible to write your operators like so:

#include <algorithm>

IntMatrix IntMatrix::operator<(int num) const {
    IntMatrix result(width(), height()); // assuming this creates a matrix with the same dimensions
    const auto count = width() * height();
    std::transform(data, data + count, result.data,
                   [num](int value){return value < num;});
    return result;
}

With this, there is no need to write your own filter() function.

\$\endgroup\$
4
  • \$\begingroup\$ Can't I fix this without using std::transform()? I am looking for personally written code, Anyway thanks for sharing \$\endgroup\$
    – user225756
    Jun 9, 2020 at 0:22
  • 5
    \$\begingroup\$ @user225756 Why? Using the standard library is usually the preferred method. \$\endgroup\$
    – Mast
    Jun 9, 2020 at 5:57
  • \$\begingroup\$ It's like an assignment and I need to write my own code instead on using some libraries \$\endgroup\$
    – user225756
    Jun 9, 2020 at 20:50
  • \$\begingroup\$ In that case, consider creating a variant of filter() that takes a function as an argument, so that you can call it like so: IntMatrix IntMatrix::operator<(int num) const { return filter(*this, [num](int value){return value < num;}); }. \$\endgroup\$
    – G. Sliepen
    Jun 9, 2020 at 20:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.