防止在执行以下操作时将两个 objects 从两个 类 转换为布尔值:if(a!=b)

Prevent converting two objects from two classes to bool when doing : if(a!=b)

我有两个 类 AB,每个都有一个 operator bool() 定义。

我最近遇到了一个由以下原因引起的错误:

A a;
B b;
if(a!=b)
{
    //...
}

代码在 gcc 4.9.1 下编译良好,并在比较前将 a 和 b 隐式转换为 bool。

是否可以定义一些东西来阻止这种情况并导致编译错误,以强制程序员使用 A 和 B 提供的显式转换函数? A 和 B 的声明应该是无关的,它们在不同的 headers.

最明显的方法是在 AB(或两者)中显式标记 operator bool()。这将导致编译器错误。请记住,它可能会导致 AB 的某些其他用法(此类隐式转换按预期工作)也无法编译。天下没有免费的午餐。

代码的目的大概是比较对象(或以某种方式比较它们的数据成员)。如果是这样 [那是您的设计选择] 也值得提供

  bool operator!=(const A&, const B&);      // usage a != b
  bool operator!=(const B&, const A&);    //   usage b != a

根据类型,按值传递一个或多个可能是合适的。另一种方法(例如,如果两种类型都是 struct/class 类型)是将 bool operator!=(const B &) const 作为 A、and/or bool operator!=(const A &) const 的成员实现为B.

的成员

请记住,如果为两种类型提供 operator!=(),则提供其他比较运算符(例如 ==)也可能是合适的。不过,这是一个设计决定。

另一个 "hack" 会像 M.M 已经提到的那样使 bool 转换显式,但这会带来一些其他问题。

像这样:

class A {  // same for class B
public:
    explicit operator bool() {
        // some code
        return (true || false) && !(false && true);
    }
};

现在 if(a==b) 将不再编译,但 if(a)if(b) 会。 HOWEVER,这将导致一些其他问题和意外行为,例如 if(a==true) 也不会再编译,因为 a 被转换为整数;这也是 if(a==b) 首先编译的原因。

另一种选择是删除隐式 int 转换:operator int() = delete;

Here 是一个示例,您可以试一试,看看如果乱用转换运算符会发生什么...