为什么在c++中不应重载逗号、地址、逻辑AND和逻辑OR运算符
why comma,address-of, logical AND and logical OR operators should not be overloaded in c++?
有人能举例说明为什么在c++中重载逗号、地址、逻辑AND和逻辑OR运算符不是一种好的做法吗?
根本原因是这些运算符的重载版本的行为与内置版本不同。这可能会导致(人类)在读/写代码时出现严重的混乱。
-
逻辑运算符
&&
和||
内置版本表现出短路优化:在像a && b
这样的表达式中,首先评估a
,并且仅当同时评估true
、b
时;类似地,在a || b
中,首先评估a
,并且仅当还评估false
、b
时。重载运算符&&
和||
不具有短路优化(总是对a
和b
进行求值),并且也没有指定参数的求值顺序。 -
逗号运算符内置版本保证按参数出现的顺序计算参数,即在
a,b
中,先计算a
,然后计算b
。对于重载的逗号运算符,这种保证将丢失(取而代之的是函数参数机制)。 -
运算符的地址当应用于不完整类型的对象时,运算符
&
的内置地址和重载地址之间可能存在混淆。考虑这个代码struct type; // forward declaration: type is (as of yet) incomplete #include <memory> void foo(type &obj) // allowed: take object of incomplete type by reference { auto ptr1 = &obj; // address of obj -- or not? auto ptr2 = std::addressof(obj); // always address of obj } // possibly in a different translation unit: struct type { type* operator&() { return nullptr; } };
此代码表现出未指定的行为:编译器可以在
foo()
中实现&
运算符的任何一个版本,但编写foo()
代码的人无法知道将使用此运算符或哪个运算符。当使用std::addressof
作为ptr2
时,即使type
具有过载的&
运算符,也避免了这个问题,因为CCD_23获得了运算符的内建地址的等价值。
如果有人阅读代码并看到if(a && b)
,他/她会怎么想
如果a和b是像bool
或int
这样的原生类型,那么每个人都知道它是如何工作的。
如果它们是类对象,大多数人会期望该类在应用&&
之前提供一个operator bool()
或类似的对象来查询它应该是什么布尔。没有人会认为这是一种"奇特"的编写if(a.myMethod(b))
的方式,也没有人会检查类定义=>每个人都会误解和/或混淆条件的用途。
tldr,不要使用内置的&&
作为不相关方法调用的缩写。
这同样适用于||
和,
。
至于地址运算符,除了读取混淆问题外,它在编写代码时也很常见:指针地址通常可以为任何类型的任何变量获取,在这样做之前,没有人会检查类定义。
除了可读性等之外,是否以及按何种顺序评估参数也有所不同:
对于if(a&&b)
,如果a是false
,则b
甚至不再被检查,因为整个条件只能为false。如果您有类似if(a && func1()) func2();
的东西,其中func2()
的返回值很重要,则仅当a
为true
时执行func1()
,并且仅当两者都为真时执行func2()
。对于过载的&&
,func1()
总是执行。根据它的作用,这可能不是你想要的。
对于||
,它是类似的:如果第一个参数是true
,那么第二个参数通常不再被查看,因为整个条件无论如何都是真的。使用重载时,始终对参数进行求值。
一个普通的逗号运算符CCD_ 48保证CCD_;在过载的情况下,它可以是任何顺序。
- C++选择排序算法中的逻辑错误
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- C++核心准则 C35 对于接口类"A base class destructor should be either public and virtual, or protected and nonv
- 为什么C++逐位AND运算符在不同大小的操作数中表现为这样
- 为什么 Clang 不允许"and"作为函数名称?
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 位阵列上的快速AND运算
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- 逻辑运算符上出现错误代码 a')'
- 保证逻辑 AND 表达式中的函数调用
- 为什么按位 OR 和 AND 逻辑无法按预期工作?
- 使用逻辑 AND (&&) 时,如何以编程方式查看C++中不满足哪些条件?
- 关于正则表达式与Boost的逻辑AND和OR匹配的说明
- 逻辑AND运算对流输出的作用
- 为什么在c++中不应重载逗号、地址、逻辑AND和逻辑OR运算符
- 如何使用逻辑 AND 运算符 (&&) c++ 调用这两个函数
- 这是逻辑"and"运算符的正确用法吗?
- c++中的逻辑AND+赋值,安全
- 为什么 GCC 不能优化逻辑/按位 AND 对"x && (x & 4242)" "x & 4242"?
- 逻辑运算符 - 替换 && 和 ||在 C++ 中使用 AND 和 OR