Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在C++;初始值设定项列表_C++_Initialization_Initializer List - Fatal编程技术网

C++ 在C++;初始值设定项列表

C++ 在C++;初始值设定项列表,c++,initialization,initializer-list,C++,Initialization,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 {

我试图理解{}初始值设定项语法的全部功能

我用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,两个初始值设定项具有相同的数据类型:无符号long long int。我认为,myChar2的初始化已经发生,因为初始化器的值对于char数据类型来说太大

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


我在这里的理解正确吗?如果参数是整数文字,初始值设定项列表的行为是否会有所不同?

编译器似乎默认情况下认为类型
char
类似于类型
有符号char

在这些声明中

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

char myChar2 {128ULL};
初始值设定项具有正值,并且正值
128
不能在带符号字符类型的对象中表示

类型符号字符可以表示的最大正值为
127
。这就是值的范围是
[-128127]

因此编译器发出警告

为了这个声明

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的初始化,因为使用长双精度 初始化int可能会丢失数据。至少,ld的分数部分将为 截断的。此外,ld中的整数部分可能太大,无法放入int

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

如果使用
constexpr int i=0而不是?这将使静态确定初始化是否有问题变得更加简单。您好,谢谢您的回复。如果初始值设定项列表防止信息丢失,为什么
char myChar{127ULL}不发出警告?不改变有符号的大小,数据类型从无符号Long Long Int缩小到有符号Char count,这就是信息丢失吗?@thatmarkdude理想情况下,我们应该始终努力防止任何类型的数据丢失。所以列表是通过防止数据丢失来完成其工作的,但有时我们知道数据会因我们的操作而丢失,但我们仍然不关心它,并且在这种情况下使用了括号。您好,感谢您的回复。好的,我现在明白了,如果初始化值在编译时已知,并且在初始化变量的允许范围内,那么不会发出警告。如果在编译时未知,并且数据类型较大,则会发出警告。