防止在执行以下操作时将两个 objects 从两个 类 转换为布尔值:if(a!=b)
Prevent converting two objects from two classes to bool when doing : if(a!=b)
我有两个 类 A
和 B
,每个都有一个 operator bool()
定义。
我最近遇到了一个由以下原因引起的错误:
A a;
B b;
if(a!=b)
{
//...
}
代码在 gcc 4.9.1 下编译良好,并在比较前将 a 和 b 隐式转换为 bool。
是否可以定义一些东西来阻止这种情况并导致编译错误,以强制程序员使用 A 和 B 提供的显式转换函数? A 和 B 的声明应该是无关的,它们在不同的 headers.
最明显的方法是在 A
或 B
(或两者)中显式标记 operator bool()
。这将导致编译器错误。请记住,它可能会导致 A
或 B
的某些其他用法(此类隐式转换按预期工作)也无法编译。天下没有免费的午餐。
代码的目的大概是比较对象(或以某种方式比较它们的数据成员)。如果是这样 [那是您的设计选择] 也值得提供
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 是一个示例,您可以试一试,看看如果乱用转换运算符会发生什么...
我有两个 类 A
和 B
,每个都有一个 operator bool()
定义。
我最近遇到了一个由以下原因引起的错误:
A a;
B b;
if(a!=b)
{
//...
}
代码在 gcc 4.9.1 下编译良好,并在比较前将 a 和 b 隐式转换为 bool。
是否可以定义一些东西来阻止这种情况并导致编译错误,以强制程序员使用 A 和 B 提供的显式转换函数? A 和 B 的声明应该是无关的,它们在不同的 headers.
最明显的方法是在 A
或 B
(或两者)中显式标记 operator bool()
。这将导致编译器错误。请记住,它可能会导致 A
或 B
的某些其他用法(此类隐式转换按预期工作)也无法编译。天下没有免费的午餐。
代码的目的大概是比较对象(或以某种方式比较它们的数据成员)。如果是这样 [那是您的设计选择] 也值得提供
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 是一个示例,您可以试一试,看看如果乱用转换运算符会发生什么...