C++ 布尔复合赋值中的隐式转换?

C++ 布尔复合赋值中的隐式转换?,c++,boolean,language-lawyer,implicit-conversion,C++,Boolean,Language Lawyer,Implicit Conversion,我想了解在以下情况下会发生什么: bool b = false; float f = 3.14; char c = 1; int i = 2; unsigned int u = 3; long long int ll = 4; unsigned long long int ull = 5; b += f; b += c; b += i; b += u; b += ll; b += ull; b &= f; b &= c; b &= i; b &= u; b &

我想了解在以下情况下会发生什么:

bool b = false;
float f = 3.14;
char c = 1;
int i = 2;
unsigned int u = 3;
long long int ll = 4;
unsigned long long int ull = 5;

b += f;
b += c;
b += i;
b += u;
b += ll;
b += ull;

b &= f;
b &= c;
b &= i;
b &= u;
b &= ll;
b &= ull;

b <<= f;
b <<= c;
b <<= i;
b <<= u;
b <<= ll;
b <<= ull;

所有这些情况下的相关转换都是布尔转换[conv.bool]:

算术、非范围枚举、指针或指向成员类型的指针的prvalue可以转换为 类型
bool
的PR值。零值、空指针值或空成员指针值转换为
false
; 任何其他值都将转换为
true
。对于直接初始化(8.5),可以使用类型为
std::nullptr\u t
的PR值 转换为类型为
bool
的PR值;结果值为
false

除了两个例外:

b &= f;
b <<= f;
相反,根据类型的不同,我们将分成三种转换之一。对于
char
bool
,我们进行了整体促销,[conv.prom]:

整数类型的PR值,而不是其整数转换的
bool
char16\u t
char32\u t
wchar\u t
秩(4.13)小于int的秩,如果
int
可以表示所有值,则可以将int的秩转换为int类型的pr值 源类型的值;否则,可以将源prvalue转换为类型为
unsigned的prvalue
int

[…]
bool
类型的PR值可以转换为
int
类型的PR值,
false
变为零,
true
成为一个

对于其他积分类型,从[conv.integral]进行积分转换:

整数类型的prvalue可以转换为另一个整数类型的prvalue。未限定范围的值 枚举类型可以转换为整数类型的prvalue。
[…]
如果目的地类型是有符号的,如果可以在目的地类型中表示,则该值不变; 否则,该值由实现定义

对于
float
,从[conv.fpint]进行浮点积分转换:

浮点类型的prvalue可以转换为整数类型的prvalue。转换截断; 也就是说,小数部分被丢弃。如果无法删除截断的值,则行为未定义 在目标类型中表示


对于复合赋值表达式,首先将右操作数转换为左操作数的类型(C++14 5.17 p3):

如果左操作数不是类类型,则表达式将隐式转换(第4条)为左操作数的cv非限定类型

因此,等效假设运算符应采用布尔参数:

class bool {bool& operator op=(bool x) noexcept;};
下面是一个示例,如果您使用
int
,则会产生不同的效果:

#include <iostream>

struct Bool {
  bool value;

  Bool(bool value) : value(value) { }
  Bool &operator += (int x) noexcept { value += x; return *this; }
};

int main()
{
  Bool fake_bool = false;
  bool real_bool = false;

  fake_bool += 0.1;
  real_bool += 0.1;
  std::cout << fake_bool.value << "\n";
  std::cout << real_bool << "\n";
}
class bool {bool& operator op=(bool x) noexcept;};
#include <iostream>

struct Bool {
  bool value;

  Bool(bool value) : value(value) { }
  Bool &operator += (int x) noexcept { value += x; return *this; }
};

int main()
{
  Bool fake_bool = false;
  bool real_bool = false;

  fake_bool += 0.1;
  real_bool += 0.1;
  std::cout << fake_bool.value << "\n";
  std::cout << real_bool << "\n";
}
0
1