我有这个源文件:
#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**)':
中,A(int)'不明确 autoCast.cpp:4:注意:候选人是:A :: A(const A&amp;)
autoCast.cpp:13: error: call of overloaded
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 :(得分:4)
这是因为0
是空指针常量并且可以转换为 unsigned long 或指针,因此选择它是不明确的。草案C ++标准部分4.10
指针转换表示(强调我的):
空指针常量是整数类型的整数常量表达式(5.19)prvalue,其求值为零或者类型为std :: nullptr_t的prvalue。 空指针常量可以转换为指针类型;结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开来。
虽然1
不是空指针常量。虽然0UL
也可以转换为指针,但它更适合 unsigned long 构造函数,因为不需要转换。
答案 1 :(得分:0)
文字0
通常用于初始化指向null的指针(现代C ++应该使用nullptr
代替)。但是,直接用任何其他整数文字初始化指针是比较常见的(除了在例如使用内存映射的嵌入式系统中)。
因此,编译器正在将0
视为指针或整数,这意味着它可以调用构造函数。相反,它只将1
视为整数。