繁体   English   中英

在 { } | 内缩小从 int 到 char 的转换 char 的签名问题

[英]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_∞


所以,我的问题是:

  1. 如果char的签名是问题,那么在这种情况下,独立版本的charchar工作的? 参考 stackoverflow 上的这个线程,同一个编译器是如何为vector<char>选择signed char和为char选择unsigned char的?

  2. 如果我对问题的推断是错误的,那么这个问题背后的正确原因是什么?

1+5是一个int ,因此使用它来初始化vector<int>条目没有问题。

'r' + 's'是一个int (236),它超出了系统上的char范围。 因此,尝试使用它来初始化vector<char>条目时出现问题。 这正是关于列表初始化不允许缩小转换的规则所设计的那种情况。

对于vector<char> x = { 'a', 'b', 123456 };你会得到同样的错误。

独立char具有与signed charunsigned 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM