0值的自动整数转换失败

automatic integer conversion of a 0 value fails

本文关键字:整数 转换 失败      更新时间:2023-10-16

我有这个源文件:

#include <ctime>
class A
{
public:
A(unsigned long i){};
A(const tm*){};
};
int main(int argc, char** argv)
{
A tit(1);
A tat(0);
return 0;
}

当我使用gcc 3.4.2编译它时,我得到了以下内容:

autoCast.cpp:函数int main(int, char**)':
autoCast.cpp:13: error: call of overloaded
中的A(int)'不明确
autoCast.cpp:4:注意:候选为:A::A(const A&)
autoCast.cpp:7:注意:A::A.(const tm*)
autoCast.cpp:6:注意:A::A(long unsigned int)

我的问题是:为什么创建A tit(1)(第12行)成功,而创建A tat(0)(第13行)失败?我在这些行中尝试了不同的参数类型(例如0ULL和1ULL),但当参数值为0时,它总是失败,而当参数值是1时,它成功了。唯一没有引发错误的0值是0UL(因为我想不需要转换)。为什么在这种情况下,值为0的整数与值为1的整数得到不同的处理?它是否与time.h中定义的tm结构有关?

这是因为0空指针常量,可以转换为无符号长或指针,因此选择哪个不明确。C++标准草案4.10指针转换说(强调矿):

空指针常量是整数类型的整数常量表达式(5.19)prvalue,其求值结果为零或std::nullptr_t类型的prvalue空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的其他值区分开来。

1不是空指针常量。虽然0UL也可以转换为指针,但它与无符号长构造函数更匹配,因为不需要转换。

文字0通常用于初始化指向null的指针(诚然,现代C++应该使用nullptr)。然而,直接用任何其他整数文字初始化指针是相对罕见的(例如,在使用内存映射的嵌入式系统中除外)。

因此,编译器将0视为指针或整数,这意味着它可以调用任一构造函数。相反,它将1简单地视为一个整数。