Post

promotion

c++里的一些类型promotion,先随便看看一元+操作符的使用技巧

不过若是操作数为整数或无作用域枚举类型,一元 + 操作符会执行 Integral promotion,此时会发生隐式转换。例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// unscoped enumeration
enum Enum : unsigned int {
  enum_val_a,
  enum_val_b,
  enum_val_c
};

int main() {

  bool b = true;
  +b; // int

  +enum_val_b; // unsigned int

  char c = 'c';
  +c; // int

  unsigned short s = 10;
  +s; // int

  int array[10];
  +array; // int*
}

对于一些奇怪的类型,比如 std::uint8_t,它的类型是什么呢?顾名思义应该是 8-bit 的 Unsigned integer,然而实际上它是 unsigned char 的 typedef。那么在输出的时候就会遇到一些问题:

1
2
std::uint8_t u = 0x45;
std::cout << u; // E

这里的输出结果是 E,而不是 69,因为 std::cout 会将 char 类型的参数当作字符输出。而借助一元 + 操作符,则可以非常简单地达到预期。

1
2
std::uint8_t u = 0x45;
std::cout << +u; // 69

还有一个是lambda的问题,正常lambda的类型是一个closure,但是+之后可以转换成函数指针

1
2
auto fp = +[]{};
static_assert(std::is_same_v<decltype(fp), void (*)()>);

还有一些用法在concept中,不熟。

char和uint8

char在大多情况下是个有符号数,有些编译器可能是无符号的。uint8是一个name alia

char转成uint8在[0, 127]是对的,[-128, -1]对应[128, 255]

在做字节流的时候互相用用可能还好,但是如果生成uint8, 传出去给int,这个时候再去拿int当无符号数就会发生傻逼事情。。。

所以在用无符号数的时候,尽量都用无符号数接着,不要转成有符号数再转回来

取模运算

准确的说这个不算promotion,只不过最近遇到了写一下。a % min(c, d);

要确保一件事,c和d里不要有0,否则会发生除0错误

除法和取模都要保证不要拿0做底

This post is licensed under CC BY 4.0 by the author.

Trending Tags