在 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 的两倍,这构成了缩小,因此给出了编译器警告。
但是对于 myChar 和 myChar2,两个初始化器具有相同的数据类型: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,这就是编译器发出的警告。
我正在尝试了解 {} 初始化程序语法的全部功能。
我用 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 的两倍,这构成了缩小,因此给出了编译器警告。
但是对于 myChar 和 myChar2,两个初始化器具有相同的数据类型: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,这就是编译器发出的警告。