我正在将代码库从一种编程风格转移到另一种编程风格。
我们有一个称为Operand
的类型,定义如下:
class Operand
{...};
然后我们有
class OperandFactory
{
public:
const Operand *make_operand (...);
};
OperandFactory
用于对Operand
进行哈希处理并将其保存在表中。因此,如果使用相同的参数调用make_operand
,则在Operand
泛滥的情况下,您将获得相同的指针和指针比较。现在,我需要添加一个使之不可行的功能。因此,我在operator==
中实现了Operand
,并且如果我在Operand
上进行了指针比较,则想以某种方式在编译时(更好)或运行时(总比没有好)生成错误。实现此目标的最佳方法是什么?这仅在过渡阶段使用,因此我不介意该解决方案看起来像黑客一样,只要它能够捕获代码库中的所有比较。
最佳答案
您可以重载运算符的地址以返回一个句柄并声明两个句柄的比较(无定义)。这将导致链接器错误。
#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 */
}
}
注意:
您必须满足
random_access_iterator
的Handle
要求!Op i{10}
Handle ref = &i;
ref++; ref--; ++ref; --ref; ref = ref + 10; ref = ref - 10; // should all work.
关于c++ - 避免指针比较的C++技巧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25549422/