指针和整数的模棱两可的重载?

问题描述

以下重载函数

void foo(const void*)
{
  printf("first");
}

void foo(unsigned int)
{
  printf("second");
}

在这种情况下会产生歧义

foo((int)0);

但不在此

foo((int)1);

为什么?是因为人们仍然使用NULL吗?而没有显式强制解决问题的最佳方法是什么?

(我正在Ubuntu 18.04上使用GCC 8.3.0-C ++ 11进行编译)

Godbolt conformance view

编辑

正如您在注释中指出的那样,(int)0实际上编译时没有错误(至少在GCC 8.3.0中,使用C ++ 11 std)。我只遇到了foo(0)的问题,现在我明白了为什么。

解决方法

文字0在C和C ++中具有特殊含义,因为它也是空指针文字。 NULL就是这样的。

如果您使用文字而不是foo(0)来调用函数,则可以执行foo(0u),这是有效的,因为0u已经具有类型unsigned int,所以有无需调用整数重载就可以进行转换。如果您使用整数变量调用foo,则不应有任何冲突。 (演示here

如评论中所述,(int)0不应引起任何冲突,在C ++ 11模式下,foo((int)0)的GCC 8.3 doesn't produce any error与C语言的does ++ 98模式(clang也是如此)。正如@ StoryTeller-UnslanderMonica在评论中提到的,这是由缺陷http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#903引起的,该缺陷未追溯应用于C ++ 98。