1

Important Note: I am coding according to C++11 standard

I have to write the following operators for my IntMatrix class (which check if every element in the matrix is <,>,==,!=,etc... the given parameter):

    IntMatrix operator< (int num) const;
    IntMatrix operator> (int num) const;
    IntMatrix operator>= (int num) const;
    IntMatrix operator<= (int num) const;
    IntMatrix operator== (int num) const;
    IntMatrix operator!= (int num) const;

So, to prevent code duplications and since the implementation is nearly the same I thought about writing one functor called between(int from, int to) which checks if number is in a given field.

For example:

for operator> I would use between(num+1,LargestPossibleint)

for operator<: between(SmallestPossibleInt,num-1)

for operator==: between(num,num)

for operator!=: between(num+1,num-1)

But as you can see my code depends of values like LargestPossibleint and SmallestPossibleInt which I don't want, (And don't believe this is a good solution) May someone suggest an edit for this (Maybe default value for parameters may help)?

Update: I can't use lambda, macros or anything not in standard level What I learnt? All basic stuff in C++, classes, functors, operation overloading, templates, generic code...

  • 1
    Does this answer your question? [What are the basic rules and idioms for operator overloading?](https://stackoverflow.com/questions/4421706/what-are-the-basic-rules-and-idioms-for-operator-overloading) – dfrib Jun 06 '20 at 12:54
  • As an aside, this is a common complaint. So much so that they standardized a new operator, <=> to reduce all the boilerplate. Soon we'll have metaclasses that can help too – AndyG Jun 06 '20 at 12:55
  • If using C++20, look up the "spaceship operator" for a starting point. – Peter Jun 06 '20 at 12:56
  • @dfri no, my question is completely different –  Jun 06 '20 at 12:57
  • @Peter I am using C++11 –  Jun 06 '20 at 12:57
  • In what way is the dependence on largest possible int or smallest possible int an issue? There is a facility called "std::numeric_limits" with functions for this, so you don't have to worry about those values being different for different compilation targets. Also, depending on how often those matrices are manipulated compared to how often those expressions comparisons are made, you may just want to store a int max and int min and update them when the numbers in the matrix are changed. That could simplify (and speed up) the implementation of those operators. – Ikaros Jun 06 '20 at 13:04
  • so maybe you should provide `all_elements_between` but not provide the operators? The way you define them is not intuitive – Sopel Jun 06 '20 at 13:09
  • @Ikaros I like the solution of int max and int min, But isn't storing values to be used only by one functions "not smart"? –  Jun 06 '20 at 13:23
  • @clark_smith That depends. If you build one large matrix and compare it to many numbers, then you are implicitly calculating min and max over and over, walking over all values every time, which is certainly not smart either. The cost of storing those values is the size of two ints, i.e. O(1), while the matrix might be much larger anyways. On the other hand, if you almost never call those comparisons, then updating min and max each time you change a value in the matrix might be bad, so it really depends on how that matrix is used. – Ikaros Jun 06 '20 at 13:26

2 Answers2

3

You could use templates and write the following function:

template<class Comp>
bool cmp_with(int num, Comp cmp) const {
    for(size_t i =0 ; i < width; ++i) {
         for(size_t j = 0; j< height; j++) {
             if(!cmp(matrix[i][j], num)) { 
                 return false;
             }
         }
    }
    return true;
}

Of course, you have to adapt this with your element access etc. Then use it like this:

bool operator<(int num) const {
    return cmp_with(num, std::less<int>{});
}

and so on. See here for the different function objects (like std::less) you need.

n314159
  • 4,990
  • 1
  • 5
  • 20
  • I'm not allowed to use this –  Jun 06 '20 at 13:13
  • @clark_smith What specifically in this are you not allowed to use? – Ikaros Jun 06 '20 at 13:16
  • The update does not exclude anything used in my answer. – n314159 Jun 06 '20 at 13:25
  • @Ikaros - the constraints on the question suggest this is a homework exercise. It's fairly common for homework exercises to require implementing things without using anything from the standard library other than I/O, without using macros (although I wouldn't use them anyway in C++), ..... – Peter Jun 06 '20 at 13:26
1

No lambda? Macrology!

#define ALLOF(op) \
bool operator op (int num) const { \
    for (auto& v : data) if (!(v op num)) return false; \
    return true; \
}
ALLOF(<)
ALLOF(<=)
ALLOF(>)
ALLOF(>=)
ALLOF(==)
ALLOF(!=)
#undef ALLOF
6502
  • 112,025
  • 15
  • 165
  • 265
  • Sorry! forgot to mention my professor believes that define and macros are always bad solutions... –  Jun 06 '20 at 13:11
  • 1
    @clark_smith: Most of the times they're bad indeed... but always question someone that uses the word "always" in IT ;-) – 6502 Jun 06 '20 at 13:14
  • @6502 This is just horrible. I love it ;-) – n314159 Jun 06 '20 at 13:22