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
vsint
到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的所有参数的转换,以及
好了,从这里开始,请参考..中的表格。恐怕这真的可以归结为“因为它是” 整数提升在
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) {}