2

I am writing a CheckedPtr class to practice exception handling (Stroustrup, TC++PL Exercises, 4th Ed., problem 14.1). I want to overload a bunch of operators, and the code to do this is almost the same. I am using macros to avoid being too repetitive, but I know macros are dangerous, so I was wondering if a better method exists.

Here is my code -- the portion shown is part of what I defined within a class called CheckedPtr. Can I do it better, and/or without macros? I would rather not write all of these functions manually, even if it means some risk with macros.

// This is relatively dangerous.
#define CHECKED_PTR_OVERLOAD_COMPARATOR(OP)            \
    template<typename Ptr>                             \
    bool operator OP(Ptr& p) { return pos OP &*p; }

    CHECKED_PTR_OVERLOAD_COMPARATOR(==)
    CHECKED_PTR_OVERLOAD_COMPARATOR(<)
    CHECKED_PTR_OVERLOAD_COMPARATOR(>)
    CHECKED_PTR_OVERLOAD_COMPARATOR(<=)
    CHECKED_PTR_OVERLOAD_COMPARATOR(>=)

#undef CHECKED_PTR_OVERLOAD_COMPARATOR
  • In this example I don't see that your macro is buying you much tbh. – Galik Aug 11 '15 at 02:43
  • Is it really that bad to repeat the code? These functions are so trivial. I don't think using the macro even makes the code simpler. On the contrary, reading the macro code seems more complicated to me in this case. – 5gon12eder Aug 11 '15 at 02:45
  • Don't do it. You seem to realize that you're balancing between two evils; but compiler messages, debuggers, real-time code parsers, and other programmers have all evolved *away* from macros. These comparison functions are a very small part of a real programming project. Just write them normally. – Drew Dormann Aug 11 '15 at 03:10

1 Answers1

1

As the commenters have already said, do not use macros for this. If you want to have a minimal implementation but a complete set comparison functions, I believe Boost.Operators is your best bet. The example shown on the page I linked to is:

struct animal : public boost::less_than_comparable<animal>
{
  std::string name;
  int legs;

  animal(std::string n, int l) : name{std::move(n)}, legs{l} {}

  bool operator<(const animal &a) const { return legs < a.legs; }
};

where implementing the single operator< function and having the animal class derive from boost::less_than_comparable<animal> gives you the operators >, <=, and >=.

There are other questions on stackoverflow that are related. See

how to use std::rel_ops to supply comparison operators automatically?

How do boost operators work?

Community
  • 1
  • 1
Phil
  • 5,822
  • 2
  • 31
  • 60
  • So, just making sure, there is no safe method to do this as generically as I did with macros. Boost operators seem to be better -- however I don't think it makes sense to work with a whole new library for such a small program, especially since I am still learning C++. I will switch to plain code, even though for larger implementations, your way is better. Thanks. – Akash Gaonkar Aug 11 '15 at 03:55
  • Yes, for a small program as you are learning, do these things directly. But boost seems ubiquitous for all but those under a "we use no 3rd party code" rule, so you may want to add it as step 3 after steps 1) learning the basics of the language, and 2) learning the standard library. Boost is quite large with some libraries being more accepted than others, so you will want to take it one piece at a time. – Phil Aug 11 '15 at 04:23