Search code examples
c++sfinae

c++ SFINAE - checking class has typedef, why is void_t required?


template <class T> struct has_iterator_typedefs
{
private:
    struct __two {char dummy[2];};
    template <class U> static __two test( ... );
    template <class U> static char  test( typename __void_t<typename U::iterator_category>::type*    = NULL,    //NOTE: require __void_t , == NULL ?
                                          typename __void_t<typename U::difference_type>::type*      = NULL,
                                          typename __void_t<typename U::value_type>::type*           = NULL,
                                          typename __void_t<typename U::reference>::type*            = NULL,
                                          typename __void_t<typename U::pointer>::type*              = NULL);
public:
    static const bool value = sizeof(test<T>(0,0,0,0,0)) == 1;
};

This is part of libc++ code. I understand how does void_t work, but I don't know why it is required in the context.

Why SFINAE does not work without void_t, like typename U::iterator_category*?

+) I think it does work w/o default argument = NULL, is it required?


Solution

  • you cannot have pointer to reference

    using X = int&;
    using T = X*; // fail
    

    so at least U::reference* is pretty likely to fail.


    I don't think NULLs are really necessary since the caller do provide all the value.


    note: I'm assuming __void_t is the same as std::void_t