为什么common_type< long,unsigned long> :: type = long long? [英] Why isn't common_type<long, unsigned long>::type = long long?

查看:224
本文介绍了为什么common_type< long,unsigned long> :: type = long long?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

common_type<long, unsigned long>::typeunsigned long是因为关于整数提升后的操作数,标准说...

common_type<long, unsigned long>::type is unsigned long because concerning the operands after integral promotion the standard says...

[...]如果具有无符号整数类型的操作数的秩大于或 等于另一个操作数类型的等级,该操作数具有 有符号整数类型应转换为具有以下内容的操作数的类型: 无符号整数类型

[...] if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type

不要说积分提升系统有问题,但是似乎如果有一个更大的有符号整数类型可以同时表示有符号和无符号操作数的范围,则应该使用它.

Not to call the integral promotion system buggy, but it seems like if there is a bigger signed integer type which can can represent the range of both signed and unsigned operands it should be used.

我知道某些平台可能具有long == long long,在这种情况下,上述规则可以生效.但是,如果有 可用的更大的有符号整数类型,就不应该使用它吗?

I know some platforms might have long == long long, in which case the above rule can take effect. But if there is a larger signed integral type available, shouldn't it be used?

推荐答案

首先,std :: common_type(当然还有boost :: type_traits :: common_type)使用三元运算符检索类型结果.在这种情况下,相关报价来自 CppReference ,6b)

first of all, std::common_type (and of course boost::type_traits::common_type) use the ternary operator to retrieve the type result. In this case the relevant quote comes from the CppReference, 6b)

E2和E3具有算术或枚举类型:通常的算术转换将它们带到通用类型,该类型就是结果.

E2 and E3 have arithmetic or enumeration type: usual arithmetic conversions are applied to bring them to common type, that type is the result.

有了这些信息,我们可以在

With this information we can find the rules for the usual arithmetic conversions in the c++ standard, 5p10, page 88.

-否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则应将具有符号整数类型的操作数转换为具有无符号整数类型的操作数的类型

— Otherwise, if the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the operand with signed integer type shall be converted to the type of the operand with unsigned integer type.

基本上,您的问题的答案是: ...因为该标准如此规定.

So basically the answer to your question is: ...because the standard says so.

但是您不是唯一发现此行为意外的人.这是一个可以快速运行的示例:

But you are not the only one finding this behavior unexpected. Here's a quick runnable example to try:

#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;
}

但是,目前的行为是一个问题,已知已知,并且存在提案以消除某些意外情况

But that the current behavior is a problem is known, and a proposal exists to remove some of the surprises.

-汉斯(Hannes)

-Hannes

这篇关于为什么common_type&lt; long,unsigned long&gt; :: type = long long?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆