std::format对有符号字符型和无符号字符型的处理不同。

3
这种行为是预期的还是符合标准(使用VC编译器)? 示例1(有符号字符):
char s = 'R'
std::cout << s << std::endl;         // Prints R.
std::cout << std::format("{}\n", s); // Prints R.

示例2(无符号字符):

unsigned char u = 'R';
std::cout << u << std::endl;         // Prints R.
std::cout << std::format("{}\n", u); // Prints 82.

在第二个使用 std::format 的例子中,u 被打印为 82 而不是 R,这是一个错误还是预期行为?
如果不使用 std::format,只使用 std::cout,我在两个例子中都可以得到 R

除外:plain char 是有符号还是无符号类型是实现定义的。它也是与 signed char 和 unsigned char 类型都不同的类型。 - Avi Berger
请不要在标签中垃圾邮件C++版本。std::format在旧版C++中不可用。 - 273K
2个回答

9
这是故意这样规定的,并在标准中明确说明了。
char和unsigned char都是基本的数字类型。通常只有char具有表示字符的附加含义。例如,没有unsigned char字符串字面量。如果使用unsigned char,通常可以将其别名为std::uint8_t,那么它通常应该表示数值(或原始内存字节,虽然std::byte更好)。
因此,默认情况下,选择数字解释unsigned char和字符解释char是有意义的。在两种情况下,可以通过{:c}作为字符解释的格式说明符和{:d}作为数字解释的格式说明符来覆盖默认设置。
我认为operator<<的行为是非直观的,但它已经存在很长时间,可能无法更改。
此外,请注意,signed char是与char和unsigned char完全不同的类型,并且实现定义了char是有符号还是无符号整数类型(但始终与signed和unsigned char不同)。
如果使用signed char,则由于与unsigned char相同的原因,默认情况下也会被解释为数字。

我相信这就是标准中详细说明此内容的部分:https://timsong-cpp.github.io/cppwp/format#arg-5 - NathanOliver
@NathanOliver 不是,它指的是 https://timsong-cpp.github.io/cppwp/format#string.std-19(适用于除`charT`(此处为`char`和`bool`)之外的所有整数类型)和 https://timsong-cpp.github.io/cppwp/format#string.std-20 (适用于 charT)。在每种情况下,请查看表中的“none”条目。 - user17732522

1
在第二个例子中,使用std::format输出的结果是82而不是'R',这是一个问题还是标准行为?
根据[format.string.std],这是标准定义的行为。
类型 含义
... ...
c 将字符static_­cast<charT>(value)复制到输出。如果value不在charT可表示的值范围内,则抛出format_­error异常。
d to_­chars(first, last, value)
... ...
none d相同。[注8:如果格式化参数类型为charTbool,则默认分别为cs。—结束注释]

对于整数类型,如果未指定type选项,则默认为d。由于unsigned char是整数类型,它将被解释为整数,并且其值将是由std::to_chars转换的值。

(除了charT类型和bool类型外,默认的type选项为cs


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接