Dav*_*vid 20 c++ integer-promotion language-lawyer
common_type<long, unsigned long>::type是unsigned long因为关于积分推广后的操作数标准说...
[...]如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则带有符号整数类型的操作数应转换为具有无符号整数类型的操作数的类型
不要调用整数提升系统错误,但似乎有一个更大的有符号整数类型,它可以表示应该使用的有符号和无符号操作数的范围.
我知道有些平台可能长==很长,在这种情况下上述规则可以生效.但如果是一个更大的符号整数类型可用,不应该应用它呢?
首先,std :: common_type(当然还有boost :: type_traits :: common_type)使用三元运算符来检索类型结果.在这种情况下,相关的引用来自CppReference,6b)
E2和E3具有算术或枚举类型:通常的算术转换应用于将它们带到公共类型,该类型是结果.
有了这些信息,我们可以在c ++标准,5p10,第88页找到通常算术转换的规则.
- 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则带有符号整数类型的操作数应转换为具有无符号整数类型的操作数的类型.
所以基本上你的问题的答案是:......因为标准这样说.
但你不是唯一一个发现这种行为出乎意料的人.这是一个快速运行的例子:
#include <iostream>
#include <typeinfo>
#include <type_traits>
int main(int argc, const char* argv[])
{
std::cout << typeid(std::common_type<char, unsigned char>::type).name() << std::endl;
// I would expect "short", and the result is "int", ok so far.
std::cout << typeid(std::common_type<short, unsigned short>::type).name() << std::endl;
// I would expect "int", and the result is "int", yay.
std::cout << typeid(std::common_type<int, unsigned int>::type).name() << std::endl;
// I would expect "long", but the result is "unsigned int"
std::cout << typeid(std::common_type<long, unsigned long>::type).name() << std::endl;
// I would expect "long long", but the result is "unsigned long"
// So this usual arithmetic conversion can lead to unexpected behavior:
auto var_auto = true ? var_i : var_ui;
std::cout << typeid(var_auto).name() << std::endl; // unsigned int
std::cout << var_auto << std::endl; // 4294967173
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,目前的行为是一个问题是已知的,并且建议的存在是为了去除一些惊喜.
-Hannes
| 归档时间: |
|
| 查看次数: |
997 次 |
| 最近记录: |