lundi 21 octobre 2019

How does the impementation for std::is_function in libcxx work?

In ibcxx/include/type_traits, std::is_function is implemented in such compact way:

namespace __libcpp_is_function_imp
{
struct __dummy_type {};
template <class _Tp> char  __test(_Tp*);
template <class _Tp> char __test(__dummy_type);
template <class _Tp> __two __test(...);
template <class _Tp> _Tp&  __source(int);
template <class _Tp> __dummy_type __source(...);
}

template <class _Tp, bool = is_class<_Tp>::value ||
                            is_union<_Tp>::value ||
                            is_void<_Tp>::value  ||
                            is_reference<_Tp>::value ||
                            __is_nullptr_t<_Tp>::value >
struct __libcpp_is_function
    : public integral_constant<bool,
                               sizeof(__libcpp_is_function_imp::__test<_Tp(
                                      __libcpp_is_function_imp::__source<_Tp>(0))) == 1>
    {};
template <class _Tp> struct __libcpp_is_function<_Tp, true> : public false_type {};

template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_function
    : public __libcpp_is_function<_Tp> {};

I got the general idea. If a type does not match any of the non-function type (class, union, void, reference, nullptr_t), it is a function type.. However, I can't find the meaning for this line:

sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1

I think, the result type for __libcpp_is_function_imp::__source<_Tp>(0) should be _Tp&. So the result type for __libcpp_is_function_imp::__test<_Tp>(_Tp&) should be _two. And sizeof(_two) should equal to 2, which is different from 1. In other words, the equation sizeof(__libcpp_is_function_imp::__test<_Tp>(__libcpp_is_function_imp::__source<_Tp>(0))) == 1 is always false.

But I must get something wrong. Could anyone point me out?

Aucun commentaire:

Enregistrer un commentaire