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.
1 Answer 1
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.
-
\$\begingroup\$ Can't I fix this without using std::transform()? I am looking for personally written code, Anyway thanks for sharing \$\endgroup\$user225756– user2257562020年06月09日 00:22:12 +00:00Commented Jun 9, 2020 at 0:22
-
5\$\begingroup\$ @user225756 Why? Using the standard library is usually the preferred method. \$\endgroup\$2020年06月09日 05:57:24 +00:00Commented 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– user2257562020年06月09日 20:50:44 +00:00Commented 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– G. Sliepen2020年06月09日 20:55:33 +00:00Commented Jun 9, 2020 at 20:55
Explore related questions
See similar questions with these tags.
<
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\$