我有以下代码:
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.2
和clang 3.6
却恰恰相反。如果我在代码中使用uint16_t而不是auto,则正确的断言失败而另一个成功。
P.S。最初我只有1
而不是static_cast<uint16_t>(1)
并且认为问题是由数字文字1
具有int类型但错误的断言即使在显式转换后也失败的事实引起的。
答案 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
(或者可能是更大的类型,如果有必要匹配其他操作数)执行添加。
添加的结果将是提升类型。如果你想要其他类型,你必须事后转换。