![](/img/trans.png)
[英]error: narrowing conversion of ‘199’ from ‘int’ to ‘char’ inside { } [-Wnarrowing]
[英]Narrowing Conversion from int to char inside { } | An issue with signedness of char
在vector<char>
和独立char
的情况下查看char
的行为:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> someInts = {2, 3, 1 + 5};
// I can perform operations ^^^^^ inside the braces in this case
// vector<char> someChars = {'a', 'b', 'r' + 'z'};
// But doing the same in case of char ^^^^^^^^^ gives an error
// However, it works for a standalone char
char ch = 'r' + 'z';
cout << ch;
// Value^^^is '∞' as expected
}
取消对vector<char>
行的注释给出:
错误:在 {} 中缩小从 'int' 到 'char' 的 '236' 转换
这就是问题所在。
然后我阅读 了List Initialization的文档,并看到了以下可能与此问题有关的内容:
缩小转化范围
list-initialization 通过禁止以下内容来限制允许的隐式转换:
- 许多其他原因
- 从 integer 或无作用域枚举类型到 integer 类型的转换,它不能表示原始的所有值,除非 source 是一个常量表达式,其值可以完全存储在目标类型中
它让我理解了错误消息(我猜),我将vector<char>
更改为vector<unsigned char>
并且它起作用了:
vector<unsigned char> someChars = {'a', 'b', 'r' + 'z'};
for (char ch : someChars)
cout << '_' << ch;
Output:
_a_b_∞
所以,我的问题是:
如果char的签名是问题,那么在这种情况下,独立版本的char
是char
工作的? 参考 stackoverflow 上的这个线程,同一个编译器是如何为vector<char>
选择signed char
和为char
选择unsigned char
的?
如果我对问题的推断是错误的,那么这个问题背后的正确原因是什么?
1+5
是一个int
,因此使用它来初始化vector<int>
条目没有问题。
'r' + 's'
是一个int
(236),它超出了系统上的char
范围。 因此,尝试使用它来初始化vector<char>
条目时会出现问题。 这正是关于列表初始化不允许缩小转换的规则所设计的那种情况。
对于vector<char> x = { 'a', 'b', 123456 };
你会得到同样的错误。
独立char
具有与signed char
或unsigned char
相同的属性,它是实现定义的,并且一些编译器有一个开关可供选择(例如,GCC 上-funsigned-char
)。 需要明确的是,无论哪种情况,它仍然是一种独特的类型。
用你的话来说,正如 Nathan Oliver 在评论中解释的那样, char
确实在这两种情况下都有签名。 问题是您有一个错误的概念,即在您的情况下独立char
是未签名的。 只是因为char ch = 'r' + 'z';
编译并没有显示它是无符号的。 您可能认为它是无符号的,因为'r' + 'z' == 236
不适合带signed char
。 不,它确实适合signed char
,原因如下:
char ch = 'r' + 'z';
是超出范围的转换。 由于 C++20,结果将是-20
(假设普通字符是 8 位签名的,如您之前的错误消息所示,并且系统使用 ASCII 编码),在此之前结果是实现定义的。
所以,不要假设事情。 如果您对系统上的 char 是有符号还是无符号感到困惑,只需检查CHAR_MIN
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.