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

时间:2015-05-12 13:10:19

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

我有以下代码:

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类型但错误的断言即使在显式转换后也失败的事实引起的。

2 个答案:

答案 0 :(得分:16)

添加将对其操作数执行usual arithmetic conversions,在这种情况下,由于integer promotions,操作数将被提升为 int ,结果也将< EM> INT

您可以使用 uint16_t 代替自动强制转换,或者在一般情况下您可以使用public class MyModel : IMyModel { public void NotifyMoneyTypeChanged() { // do work here } }

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

供参考,来自草案C ++标准部分static_cast 添加剂运算符

  

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

和第5.7 个表达式

  

[...]否则,应执行整体促销(4.5)   两个操作数。 59 然后应适用以下规则   推广的操作数[...]

以及5 整体促销活动强调我的):

  

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

假设 int 大于16位。

答案 1 :(得分:8)

算术运算不适用于小于int的任何类型。因此,如果uint16_t小于int,则它将提升int(或者可能是更大的类型,如果有必要匹配其他操作数)执行添加。

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