在 C++ 初始化列表中使用整型文字

Using Integer Literals in C++ Initializer List

我正在尝试了解 {} 初始化程序语法的全部功能。

我用 g++ 编译了以下代码:

int i = 0;                /* OK */

short int si2 {i};        /* Warning: Narrowing Conversion inside {...} */

char myChar {127ULL};     /* OK */

char myChar2 {128ULL};    /* Warning: Narrowing Conversion inside {...} */

我对si2初始化警告的理解如下。在我的系统上: - short int 是 2 个字节 - int 是 4 个字节

因为初始化程序的大小(以字节为单位)是 LHS 的两倍,这构成了缩小,因此给出了编译器警告。

但是对于 myCharmyChar2,两个初始化器具有相同的数据类型:unsigned long long int.我相信 myChar2 的初始化已经发生,因为初始化程序的值对于 char 数据类型来说太大了。

相同的规则似乎不适用于这两种情况: 1.失败,因为初始化程序数据类型对于初始化变量来说太大 2. 由于初始化变量的值太大而失败(尽管此处可以接受 RHS 数据类型)

我的理解是否正确 - 如果参数是整数文字,初始化列表的行为是否不同?

您的编译器似乎默认认为类型 char 类似于类型 signed char.

在这些声明中

char myChar {127ULL};     /* OK */

char myChar2 {128ULL};

初始值设定项具有正值,并且正值128不能在类型为 signed char 的对象中表示。

signed char类型可以表示的最大正数是127。即取值范围是[-128, 127].

因此编译器发出警告。

对于此声明

short int si2 {i}; 

编译器发出警告,因为初始值设定项不是编译时常量。

如果你会写

const int i = 0;

然后警告消失。

记住这件事。

当与内置类型的变量一起使用时,这种初始化形式有一个 重要属性:如果初始化器可能导致信息丢失,编译器将不允许我们列出内置类型的初始化变量:

    long double ld = 5.14159265;
    int a{ld}, b = {ld}; // error: narrowing conversion required
    int c(ld), d = ld; // ok: but value will be truncated

编译器拒绝了 a 和 b 的初始化,因为使用 long double 来 初始化一个int很可能会丢失数据。至少,ld 的小数部分将是 截断。此外,ld 中的整数部分可能太大而无法放入 int。

现在进入最后两部分。 您定义了 char ,它是有符号类型的。它可以保存从 -128 到 127.But 的值,您正在尝试分配 128,这就是编译器发出的警告。