【问题标题】:Why auto is deduced to int instead of uint16_t为什么将 auto 推导出为 int 而不是 uint16_t
【发布时间】:2015-05-12 13:10:19
【问题描述】:

我有以下代码:

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,则正确的断言会失败,而另一个断言会成功。

附:最初我只有1 而不是static_cast&lt;uint16_t&gt;(1),并认为问题是由于数字文字1 具有int 类型但即使在此处显式转换后错误断言也会失败。

【问题讨论】:

标签: c++ c++11 auto integer-promotion


【解决方案1】:

加法将对其操作数执行usual arithmetic conversions,在这种情况下,由于integer promotions,操作数将被提升为int,结果也将是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加法运算符

[...]通常的算术转换是对 算术或枚举类型[...]

来自5表达式部分:

[...]否则,积分促销 (4.5) 应在 两个操作数。59 然后应应用以下规则 到提升的操作数[...]

来自4.5 部分整体促销强调我的):

除 bool、char16_t、char32_t 或 wchar_t 其整数转换等级(4.13)小于等级 如果 int 可以表示,则 int 可以转换为 int 类型的纯右值 源类型的所有值;否则,源纯右值可以 转换为 unsigned int 类型的纯右值。

假设 int 大于 16 位。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-26
      • 2017-05-29
      • 2018-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多