Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重载不明确(int->;int64\u t vs int->;double)_C++ - Fatal编程技术网

C++ 重载不明确(int->;int64\u t vs int->;double)

C++ 重载不明确(int->;int64\u t vs int->;double),c++,C++,为什么int到int64\u tvsint到double的隐式转换不明确 我原以为整数重载会优先于整数到浮点 #include <stdint.h> void foo(double) {} void foo(int64_t) {} int main() { foo(5); return 0; } 我的环境是: x86_64 g++-5.4(带-std=c++14) int64\u t在我的机器上是一个long int: /usr/include/stdint

为什么
int
int64\u t
vs
int
double
的隐式转换不明确

我原以为整数重载会优先于整数到浮点

#include <stdint.h>

void foo(double) {}
void foo(int64_t) {}

int main()
{
    foo(5);
    return 0;
}
我的环境是:

  • x86_64
  • g++-5.4(带
    -std=c++14
int64\u t
在我的机器上是一个
long int

/usr/include/stdint.h

我已经在我的测试应用程序中通过静态断言确认了这一点:

static_assert(__WORDSIZE == 64, "");
static_assert(std::is_same<int64_t, long int>::value, "");

编译器是对的。。。默认情况下,数值文本
5
的类型为
int

要进行该函数调用,必须进行重载解析,这基本上检查了转换的可行性。注意,这将是一个转换而不是升级的情况

现在,来解释为什么?我将引用CPPFerence的故事:(我知道,不是标准的替代品)

在选择最佳可行功能时:

如果是隐式的,则F1被确定为比F2更好的函数 F1的所有参数的转换并不比隐式 F2的所有参数的转换,以及

  • 至少有一个F1参数的隐式转换优于该参数的相应隐式转换 F2
  • 或者
  • 或者 现在让我们看看隐含的含义是什么:

    隐式转换序列按以下顺序组成:

  • 零或一个标准转换序列
  • 现在,让我们看看a是什么:

    标准转换顺序由以下内容组成: 订单:

  • 零或一个左值变换
  • 零或一次数字升级或数字转换

  • 好了,从这里开始,请参考..

    中的表格。恐怕这真的可以归结为“因为它是”

    整数提升在
    int
    处结束;对于大于
    int
    的类型没有升级。剩下的是两个bog标准隐式转换,碰巧它们是同样好的匹配

    [C++14:4.5/1]:
    bool
    char16\u t
    char32\u t
    wchar\u t
    以外的整数类型的PR值,其整数转换秩(4.13)如果
    int
    可以表示源类型的所有值,则小于
    int
    的秩可以转换为
    int
    类型的PR值;否则,可以将源prvalue转换为类型为
    unsigned int
    的prvalue

    [C++14:4.5/7]:
    这些转换称为积分促销

    [C++14:5/10]:
    […]此模式称为常用的算术转换,其定义如下:

    • 如果任一操作数为作用域枚举类型(7.2),则不执行任何转换;如果另一个操作数的类型不同,则表达式的格式不正确
    • 如果任一操作数的类型为
      长双精度
      ,则另一个操作数应转换为
      长双精度
    • 否则,如果其中一个操作数是
      double
      ,则另一个操作数应转换为
      double
    • 否则,如果任一操作数为浮点,则另一个操作数应转换为浮点
    • 否则,应在两个操作数上执行积分提升(4.5)[…]
    也许,当
    long int
    long long int
    的使用变得流行时(特别是通过
    cstdint
    和friends中的类型别名),可以修改标准,为这些类型引入整体促销。那么你的转换就不会模棱两可了。然而,许多现有的代码也可能被破坏

    由于改用演员阵容是一种廉价的修复方法,我怀疑标准委员会是否认为值得“修复”

    也许能说明问题的是,相对较新的固定宽度
    char
    类型可以通过以下方式进行推广:

    [C++14:4.5/2]:
    类型为
    char16\u t
    char32\u t
    wchar\u t
    (3.9.1)的prvalue可以转换为以下类型中第一种类型的prvalue,该类型可以表示其基础类型的所有值:
    int
    无符号int
    长int
    unsigned long int
    long long int
    unsigned long long int
    。如果该列表中的任何类型都不能表示其基础类型的所有值,则可以将类型为
    char16\u t
    char32\u t
    wchar\u t
    的prvalue转换为其基础类型的prvalue


    从[over.ics.user]表12中,我们得到

    正如您所看到的,整数和浮点提升具有相同的排名,整数和浮点转换具有相同的排名

    现在我们需要确定
    5->int64\t
    是整数提升还是转换。如果我们检查[conv.prom]/1,我们会发现

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

    提升在
    int
    处停止,因此我们必须查看[conv.integral]/1,它是整数转换,我们有

    整数类型的prvalue可以转换为另一个整数类型的prvalue。非范围枚举类型的prvalue可以转换为整数类型的prvalue

    这就是正在发生的事情。因此,
    5->int64\u t
    是整数转换,
    5->double
    是浮点转换,两者都排在最前面
     # if __WORDSIZE == 64
     typedef long int        int64_t;
     # else
    
    static_assert(__WORDSIZE == 64, "");
    static_assert(std::is_same<int64_t, long int>::value, "");
    
    -std=c++14 -Werror -Wall -Wextra -m64 -msse2 -msse4.2 -mfpmath=sse 
    -ftemplate-depth-128 -Wno-unused-parameter -pthread  -g -ggdb3 -O0 -fno-inline
    
    void foo(int64_t) {}