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

Time:11-11

When reading a wiki page, I found this sample code

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) };
};

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

Did I make something wrong? What would it be like in the eyes of C compilers?

CodePudding user response:

template <class U> static char is_ptr(U *);: is_ptr is a function taking a pointer to U (without a name) and returning a char.

template <class U> static char is_ptr(U (*)());: is_ptr is a function taking a function pointer (without a name), which gets no parameters and returns a U, and returns a char.

So, one gets a pointer to a U and the other a function pointer, which returns a U.

CodePudding user response:

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

An overload, not a specialization. And yes, it is superfluous. In a template accepting U* for a parameter, U can resolve to an entire function type. It's what makes is_pointer<int(*)(char)>::value be true, despite the fact int(*)(char) will not match the overload #2.

Did I make something wrong?

Since you did not make this code yourself, I don't believe you did. You correctly surmised there's a redundancy.

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

It would be an overload that gets picked for the specific case of checking a function pointer type that accepts no arguments. It conveys no interesting information compared to the U* overload, and can be removed.

It's possible this implementation was added to get around a compiler bug (where said function pointer types were not correctly handled). Modern compilers handle said function pointers correctly even if the superfluous overload is removed.

  • Related