C ++ Trick to Avoid Pointer Comparison

I am moving a code base from one programming style to another.

We have a type called Operand

, defined as:

class Operand
{...};

      

Then we had

class OperandFactory
{
  public:
    const Operand *make_operand (...);
};

      

OperandFactory

used for hash Operand

and store it in a table. Therefore, if you called make_operand

with the same arguments, you will get the same pointer versus pointer over Operand

. Now I need to add a function that will make this unreachable. So I am implementing operator==

in Operand

and would like to somehow generate compile time (better) or runtime (better than nothing) if I ever do a pointer to Operand

s comparison . What's the best way to achieve this?

This should only be used at this point in the transition, so I don't mind if the solution looks like a hack as long as it captures all comparisons in the code base.

0


source to share


2 answers


you can overload the address of the operator to return a descriptor and declare a comparison of the two descriptors (no definition). This will result in a linker error.

#include <iostream>

class Op;

class Handle {
    Op *pri_;
public:
    explicit Handle(Op *o) : pri_(o) {}
    Op *operator->() const { return pri_; }
    Op &operator*() const { return *pri_; }
};

 // force compile time errors on comparison operators
bool operator==(const Handle &, const Handle &) = delete;
bool operator!=(const Handle &, const Handle &) = delete;
bool operator>=(const Handle &, const Handle &) = delete;
bool operator<=(const Handle &, const Handle &) = delete;
bool operator<(const Handle &, const Handle &) = delete;
bool operator>(const Handle &, const Handle &) = delete;

class Op {
    int foo_;
public:
    explicit Op(int i) : foo_(i) { }
    Handle operator&() { return Handle(this); };
    void touch() const { std::cout << "foobar"; }
};


int main(int argc, char **argv) {
    Op i{10};
    Op j{20};

    auto c = &j; // works
    c->touch(); // works
    (*c).touch(); // works

    if (&j == &i) {
        /* will not compile */
    }

}

      

Note



You must fulfill the requirement random_access_iterator

for Handle

!

Op i{10}
Handle ref = &i;

ref++; ref--; ++ref; --ref; ref = ref + 10; ref = ref - 10; // should all work.

      

+3


source


Adding an operator to the class Operand

won't help: you want to define a comparison of pointers to Operand

s. Unfortunately, operators of native types cannot be overloaded, and pointers have their own type. This is not the solution you are looking for.



+2


source







All Articles