我想了解以下情况会发生什么:
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;
或者换句话说,根据标准进行的隐式转换是什么?
其他问题:如果为假设的bool
类提供的复合赋值的唯一签名将采用以下形式,结果是否相同:
class bool {bool& operator op=(int x) noexcept;}; // op <=> +,-,&,|...
答案 0 :(得分:1)
所有这些情况下的相关转换是布尔转换,[conv.bool]:
算术,无范围枚举,指针或指向成员类型的指针的prvalue可以转换为a
bool
类型的prvalue。零值,空指针值或空成员指针值将转换为false
; 任何其他值都将转换为true
。对于直接初始化(8.5),类型为std::nullptr_t
的prvalue可以 转换为bool
类型的prvalue;结果值为false
。
有两个例外:
b &= f;
b <<= f;
前者,因为[expr.bit.and]:
执行通常的算术转换;结果是操作数的按位AND功能。该 operator 仅适用于整数或未范围的枚举操作数。
和后者,因为[expr.shift]:
操作数应为整数或无范围的枚举类型,并执行整体促销。
由于float
既不是整数也不是未作用域的枚举类型,因此这两个操作无效。
如果你(以及我在这里重命名你的课程):
class Bool {Bool& operator op=(int x) noexcept;}; // op <=> +,-,&,|...
我们会根据类型分为三种转换中的一种。对于char
或bool
,我们会进行积分促销,[conv.prom]:
除
bool
,char16_t
,char32_t
或wchar_t
整数转换以外的整数类型的prvalue 如果int
可以代表所有,则rank(4.13)小于int的等级可以转换为int类型的prvalue 源类型的值;否则,源prvalue可以转换为unsigned int
类型的prvalue [...]
类型bool
的prvalue可以转换为int
类型的prvalue,其中false
变为零,true
成为一个。
对于其他整数类型,积分转换,来自[conv.integral]:
整数类型的prvalue可以转换为另一个整数类型的prvalue。一个没有眼镜的prvalue 枚举类型可以转换为整数类型的prvalue [...]
如果目标类型已签名,则该值如果可以在目标类型中表示,则不会更改; 否则,该值是实现定义的。
来自float
的浮动积分转换,来自[conv.fpint]:
浮点类型的prvalue可以转换为整数类型的prvalue。转换截断; 也就是说,丢弃小数部分。如果截断值不能,则行为未定义 以目的地类型表示。
答案 1 :(得分:0)
对于复合赋值表达式,右操作数首先转换为左操作数的类型(C ++ 14 5.17 p3):
如果左操作数不是类类型,则表达式被隐式转换(第4节)到左操作数的cv-unqualified类型。
因此,等效的假设运算符应采用bool参数:
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";
}
输出
0
1