f(U(*)()) 只是 f(U*) 的特殊版本吗?

Is f(U(*)()) just a specialized version of f(U*)?

在阅读 wiki 页面时,我发现了这个示例代码

template <class T>
struct is_pointer
{
  template <class U>
  static char is_ptr(U *); #1

  template <class X, class Y>
  static char is_ptr(Y X::*);

  template <class U>
  static char is_ptr(U (*)()); #2

  static double is_ptr(...);

  static T t;
  enum { value = sizeof(is_ptr(t)) == sizeof(char) };
};

对我来说,#2 只是#1 的特殊版本,所以它似乎是多余的。

我是不是做错了什么?在C++编译器眼中会是什么样子?

template <class U> static char is_ptr(U *);is_ptr 是一个函数,它接受指向 U(没有名称)的指针并返回 char.

template <class U> static char is_ptr(U (*)());: is_ptr 是一个接受函数指针(没有名称)的函数,它没有参数并且 returns 一个 U,并且 returns一个char.

所以,一个得到一个指向 U 的指针,另一个得到一个函数指针,returns 一个 U.

To me, #2 is just a specialization of #1, so it seems superfluous.

重载,而不是专业化。是的,这是多余的。在接受 U* 作为参数的模板中,U 可以解析为整个函数类型。这就是 is_pointer<int(*)(char)>::value 为真的原因,尽管 int(*)(char) 不会 匹配重载 #2.

Did I make something wrong?

由于您没有自己编写此代码,所以我相信您不会这样做。您正确地推测存在冗余。

What would it be like in the eyes of C++ compilers?

对于检查不接受任何参数的函数指针类型的特定情况,这将是一个重载。与 U* 重载相比,它没有传达任何有趣的信息,可以将其删除。

添加此实现可能是为了解决编译器错误(其中未正确处理所述函数指针类型)。即使删除了多余的重载,现代编译器也会正确处理所述函数指针。