对于int (*compar)(const void*, const void*)
两个不同的重载,参数具有不同的类型。对于第一个重载,它是一个extern "C"
函数指针参数。对于第二个重载,它是一个extern "C++"
函数指针参数。您传递给的任何函数指针qsort
都已经具有某种链接,这就是用来确定要调用哪个重载的。
引用标准:
7.5 联动规范 [dcl.link]
所有函数类型、具有外部链接的函数名称和具有外部链接的变量名称都具有语言链接。[...] 所有函数类型、函数名和变量名的默认语言链接是 C++ 语言链接。具有不同语言链接的两个函数类型是不同的类型,即使它们在其他方面相同。
事实上,我不认为标准实际上意味着要求两个qsort
重载确实具有不同的链接。与 C 不同,标准库函数的用户提供声明是不允许的;它们之间的相关区别是compar
. 他们可以被宣布为
extern "C" typedef int (*__compar_fnp_c)(const void *, const void *);
extern "C++" typedef int (*__compar_fnp_cxx)(const void *, const void *);
void qsort(void* base, size_t nmemb, size_t size, __compar_fnp_c compar);
void qsort(void* base, size_t nmemb, size_t size, __compar_fnp_cxx compar);
在哪里应该更明显,__compar_fnp_c
并且__compar_fnp_cxx
是不同的类型。也就是说,as-if 规则不允许这种实现,因为它会破坏采用指针或引用的代码qsort
。
请注意,GCC 以及其他一些编译器没有正确实现这一点,并且不将链接视为函数指针类型的一部分。在这样的实现中,只有一个版本的qsort
will 可用,以防止在重载解决期间发生冲突。