Re: type function U[1] and U(*)[1] SFINAE issue
On May 24, 10:28 pm, courp...@gmail.com wrote:
On 24 mai, 04:16, Barry <dhb2...@gmail.com> wrote:
a clean implementation of is_function from this NG a while ago:
by means of "function to pointer-to-function conversion"
typedef char (&yes) [1];
typedef char (&no) [2];
// is_class_type
template <typename T>
class is_class_type
{
template <typename S>
static yes check(int S::*);
template <typename S>
static no check(...);
public:
static bool const value = (sizeof(check<T>(0)) == sizeof(y=
es));
};
template <typename T>
class is_function
{
template <typename S>
static yes check(S*);
template <typename S>
static no check(...);
public:
static bool const value =
(!is_class_type<T>::value)
&&
(sizeof(check<T>(*(T*)(0))) == sizeof(yes));
};
I think the following should do the same thing but in a shorter way :
template < class T >
struct is_function {
enum { value = is_convertible<void(*)(T),void(*)(T*)>::value };
};
[------
Full working version without an "is_convertible" facility :
typedef char (&yes) [1];
typedef char (&no) [2];
template < class T >
struct is_function {
static yes test ( void(*)(T*) );
static no test(...);
enum { value = sizeof(yes) == sizeof(test( *(void(*)(T)) 0 )=
)} ;
};
------]
I didn't test this extensively though.
The rule I'm using from the Standard is :
8.3.5.3 : [...] The type of a function is determined using the
following rules. The type of each parameter is determined from its own
decl-specifier-seq and declarator. After determining the type of each
parameter, any parameter of type =93array of T=94 or =93function returning=
T=94 is adjusted to be
=93pointer to T=94 or =93pointer to function returning T,=94 respectively.=
[...]
Very impressive!
Well, the implementation I mentioned and the one you did, both have a
defect:
T can't be reference type, as "pointer to reference is not allowed"
so a specialization of is_function is needed for reference type
template <typename T>
struct is_function<T&> {
enum { value = false };
};