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.
source to share
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.
source to share