为什么将Auto推导到INT而不是UINT16_T

Why auto is deduced to int instead of uint16_t

本文关键字:UINT16 INT Auto 为什么      更新时间:2023-10-16

我有以下代码:

uint16_t getLastMarker(const std::string &number);
...
const auto msgMarker = getLastMarker(msg.number) + static_cast<uint16_t>(1);
static_assert(std::is_same<decltype(msgMarker), const int>::value, "Should fail");
static_assert(std::is_same<decltype(msgMarker), const uint16_t>::value, "Should not fail");

我希望第一个断言会失败,第二个断言不会。但是gcc 4.9.2clang 3.6做相反的事情。如果我在代码中使用uint16_t而不是自动,则正确断言失败了,另一个成功。

P.S。最初,我只有1,而不是static_cast<uint16_t>(1),并认为该问题是由于数字文字1具有INT类型而引起的,但即使在此处进行明确施放后,错误的断言也失败了。

添加将对其操作数执行通常的算术转换,在这种情况下,这将导致操作数被促进到 int 由于整数促销也是 int

您可以使用 uint16_t 而不是自动迫使转换后退或在一般情况下可以使用static_cast

对于为什么将小于 int 的类型升级为较大类型的基本原理,请参阅为什么在C和C 中算术操作之前必须将简短转换为INT。

供参考,来自C 标准部分5.7 加法操作员

[...]对操作数进行了通常的算术转换 算术或枚举类型[...]

5 extressions

[...]否则,应在 两个操作数。 59 ,则应应用以下规则 到晋升的操作数[...]

4.5 积分促销强调矿山):

除布尔,char16_t,char32_t或 WCHAR_T 其整数转换等级(4.13)小于等级 如果int可以代表,则可以将int的int转换为int类型 源类型的所有值;否则,来源可以 被转换为unsigned int类型的序言

假设 int 大于16位。

算术操作在任何类型的类型上都不小于int。因此,如果uint16_t小于int,则在执行添加之前,它将促进到int(或可能匹配其他操作数以匹配其他操作数)的

加法的结果将是晋升类型。如果您想要另一种类型,则必须在以后进行转换。