为什么 auto 被推断为 int 而不是 uint16_t

Why auto is deduced to int instead of uint16_t

我有以下代码:

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 而不是 auto 正确的断言失败而另一个成功。

P.S。最初我只有 1 而不是 static_cast<uint16_t>(1) 并认为问题是由数字文字 1 具有类型 int 但错误断言即使在此处显式转换后也会失败。

加法将执行usual arithmetic conversions on its operands which in this case will result in the operands being promoted to int due the the integer promotions,结果也将是int

您可以使用 uint16_t 而不是 auto 来强制返回转换,或者在一般情况下您可以使用 static_cast.

有关为什么小于 int 的类型被提升为更大类型的原因,请参阅 Why must a short be converted to an int before arithmetic operations in C and C++?

供参考,来自 C++ 标准草案部分 5.7 加法运算符:

[...]The usual arithmetic conversions are performed for operands of arithmetic or enumeration type[...]

来自第 5 表达式:

[...]Otherwise, the integral promotions (4.5) shall be performed on both operands.59 Then the following rules shall be applied to the promoted operands[...]

来自第 4.5 积分促销强调我的):

A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int.

假设 int 大于 16 位。

算术运算不适用于任何小于 int 的类型。因此,如果 uint16_t 小于 int,它将 提升 int (或者可能是更大的类型,如果需要匹配另一个操作数)在执行加法之前。

相加的结果将是提升后的类型。如果你想要其他类型,你必须在之后转换。