逻辑运算符

< cpp‎ | language

返回布尔运算的结果。

运算符名 语法 可重载 原型示例(对于类 class T
类内定义 类外定义
not a

!a

bool T::operator!() const; bool operator!(const T &a);
a and b

a && b

bool T::operator&&(const T2 &b) const; bool operator&&(const T &a, const T2 &b);
同或 a or b

a || b

bool T::operator||(const T2 &b) const; bool operator||(const T &a, const T2 &b);
注解
  • 关键词形式(andornot)和符号形式(&&||!)的使用可以互相代替(见代用表示
  • 所有内建运算符都返回 bool,而大多数用户定义重载亦返回 bool,以使用户定义运算符可以与内建版本相同的方式使用。然而,用户定义重载中能以任何类型为返回类型(包括 void)。
  • 内建运算符 &&|| 进行短路求值(若在求值第一个操作数后结果已知,则不求值第二个),但重载的运算符表现类似函数调用,并始终对两个操作数都进行求值。

解释

逻辑运算符的形式为

! rhs (1)
lhs && rhs (2)
lhs || rhs (3)
1) 逻辑非(NOT)
2) 逻辑与(AND)
3) 逻辑同或(inclusive OR)

若操作数并非 bool,则用按语境转换为 bool 规则将它转换为 bool:仅当对某个虚构的临时量 t,声明 bool t(arg) 良构时,它才是良构的。

其结果是 bool 纯右值。

对于内建的逻辑非运算符,若操作数为 false 则结果为 true。否则结果为 false

对于内建的逻辑与运算符,若两个运算数都是 true 则结果为 true。否则结果为 false。此运算符短路求值:若第一操作数为 false,则不求值第二操作数。

对于内建的逻辑或运算符,若第一或第二操作数之一(或两者同)为 true,则结果为 true。此运算符短路求值:若第一操作数为 true,则不求值第二操作数。

注意逐位逻辑运算符不进行短路求值。

结果

a true false
!a false true
and a
true false
b true true false
false false false
or a
true false
b true true true
false true false

面对用户定义运算符的重载决议中,下列内建函数签名参与重载决议:

bool operator!(bool)
bool operator&&(bool, bool)
bool operator||(bool, bool)

示例

#include <iostream>
#include <string>
int main()
{
    int n = 2;
    int* p = &n;
    // 指针可转换为 bool
    if(    p && *p == 2   // "*p" 在 "p &&" 后使用是安全的
       || !p &&  n != 2 ) // || 的优先级低于 &&
        std::cout << "true\n";
 
    // 流亦可转换为 bool
    std::cout << "Enter 'quit' to quit.\n";
    for(std::string line;    std::cout << "> "
                          && std::getline(std::cin, line)
                          && line != "quit"; )
        ;
}

输出:

true
Enter 'quit' to quit.
> test
> quit

标准库

因为 operator&&operator|| 的短路求值性质对重载不适用,又因为有布尔语义的类型不常见,故只有二个标准库类重载了这些运算符:

对 valarray 的每个元素应用一元算术运算符
(std::valarray<T> 的公开成员函数)
对两个 valarray 的每个元素,或一个 valarray 的每个元素和一个值应用二元运算符
(函数模板)
检查是否有错误发生(fail() 的同义词)
(std::basic_ios<CharT,Traits> 的公开成员函数)

参阅

运算符优先级

运算符重载

常见运算符
赋值 自增
自减
算术 逻辑 比较 成员访问 其他

a = b
a += b
a -= b
a *= b
a /= b
a %= b
a &= b
a |= b
a ^= b
a <<= b
a >>= b

++a
--a
a++
a--

+a
-a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

!a
a && b
a || b

a == b
a != b
a < b
a > b
a <= b
a >= b
a <=> b

a[b]
*a
&a
a->b
a.b
a->*b
a.*b

a(...)
a, b
? :

特殊运算符

static_cast 转换一个类型为另一相关类型
dynamic_cast 在继承层级中转换
const_cast 添加或移除 cv 限定符
reinterpret_cast 转换类型到无关类型
C 风格转型static_castconst_castreinterpret_cast 的混合转换一个类型到另一类型
new 创建有动态存储期的对象
delete 销毁先前由 new 表达式创建的对象,并释放其所拥有的内存区域
sizeof 查询类型的大小
sizeof... 查询形参包的大小(C++11 起)
typeid 查询类型的类型信息
noexcept 查询表达式是否能抛出异常(C++11 起)
alignof 查询类型的对齐要求(C++11 起)